Pull to refresh

Comments 9

в Swift нельзя просто вызвать free?
почему freeSMemmory не может освободить и строку тоже? почему "memmory" а не memory?..
зачем нужна длина строки в структуре? строка как была null-terminated, так и осталась
зачем два раза выделять память в функции, которая возвращает структуру?


одни вопросы

Здравствуйте! Спасибо за ваш комментарий.
в Swift нельзя просто вызвать free?

В Swift можно вызвать функцию free и передать в нее любой указатель, но так как память выделяется в Си коде, я решил ее там и освобождать. Кроме того, если вы будете использовать эти функции на другом языке программирования, то вам все равно придется как то освобождать память.
почему freeSMemmory не может освободить и строку тоже?

Я так понимаю, что тут вопрос в том, почему «freeMemmory»(она принимает параметр с void*) не может также освободить и структуру? Она может. Отвечая на ваш вопрос, потому что функции freeSMemmory ждет указатель на структуру. Вы получите ошибку типа «Cannot convert value of type 'UnsafeMutableRawPointer' to expected argument type 'UnsafeMutablePointer?'». Хотелось обратить внимание на типы данных по указателю. Можно было и обойтись, согласен.
почему «memmory» а не memory?..

Ошибся.
зачем нужна длина строки в структуре? строка как была null-terminated, так и осталась

В этом конкретном случае, вы конечно же правы. Можно считать каждый символ и смотреть не '\0' ли он. Но если у вас есть массив байт, который не обязательно закрыт, размер данных пригодится.
зачем два раза выделять память в функции, которая возвращает структуру?

Вы про то, что можно написать что то типа:
structure->result = result;

и не освобождать ее внутри? Если да, то конечно можно.
А через withUnsafeMutableBufferPointer по идее тоже можно напрямую взять указатель на array, а не выделять лишнюю память?
Честно говоря, я не пользовался, но да, действительно можно.

        var pointer: UnsafeMutableBufferPointer<UInt8>?
        array.withUnsafeMutableBufferPointer(){ bp in
                pointer = bp
        }
        guard  pointer != nil else {return nil}
        let structPointer = flipStringToStruct(pointer!.baseAddress , Int32(array.count))

На сколько я понял вы предлагаете что то такое?

Да, только весь остальной код должен быть внутри этого блока — это гарантирует что свифт не осободит память на которую ссылается указатель за ненадобностью

Рекомендую посмотреть видео Unsafe Swift c WWDC2020. В нём рассказывают, как корректно работать с небезопасной памятью и показывают несколько полезных функций. Ваш подход в статье мягко говоря не оптимален.
Очень жаль что не видел это видео раньше. Спасибо вам большое!
Ещё можно сильно упростить создание строки, используя типа такого метода: init(bytesNoCopy:length:encoding:freeWhenDone:). Там внизу перечислены разные альтернативы, выберете какой вам больше подходит под задачу.
Sign up to leave a comment.

Articles