#c #pointers #memcpy #void-pointers
#c #указатели #memcpy #пустые указатели
Вопрос:
У меня есть задание, в котором мне нужно читать и записывать в блок памяти (предварительно выделенный), для этого мне нужно реализовать две функции:
memory_read(base,offset,size);
memory_write(base,offset,size,buffer);
Пока никаких проблем, я успешно реализовал часть записи. Проблема связана с memory_read . Мне нужно, чтобы он возвращал фрагмент данных (возможно, void *), затем я могу привести его к тому, что я ожидаю снаружи, и использовать его.
Просто в качестве примера. Допустим, я записал сериализованную структуру в эту память. Я хотел бы сделать что-то вроде этого
void *variable;
variable = memory_read(pointer_to_where_it_is,offset,sizeof(some_structure);
(some_structure) variable // and use it for something
И это то, что делает memory_read
void *memory_read(void *base, int offset, int size){
void *buffer;
buffer = malloc(size);
memcpy(amp;buffer,base offset,size);
return buffer;
}
Конечно, поскольку буфер находится в стеке функций, я теряю ссылку на него при возврате.
Есть идеи, как это сделать? Мне не разрешено изменять параметры функции преподавателем, иначе я бы передал amp;переменную в качестве параметра.
Спасибо!
Комментарии:
1. Вы теряете ссылку на сам указатель, но у вас уже есть адрес, возвращаемый из функции.
2. на самом деле вы выделяете память из кучи и возвращаете указатель на эту выделенную память внутри функции
memory_read()
, так что для меня это выглядит нормально. но не используйте адрес оператора сmemcpy()
функцией, просто передайте буферную переменную, содержащую указатель напрямую,.3.
memcpy(amp;buffer,base offset,size);
:amp;buffer
—>buffer
, КСТАТИbase offset
, это UB. (это расширение gcc)4. @BLUEPIXY UB? Это просто незаконный код в стандартном C? стандарт позволяет его компилировать?
5. @ikh да, арифметика указателей на
void *
недопустима в стандарте. попробуйте gcc с опцией-pedantic
.
Ответ №1:
В этой строке:
memcpy(amp;buffer,base offset,size);
проблема в том, что вы пытаетесь скопировать блок памяти в переменную, выделенную стеком buffer
, вместо блока памяти, выделенного в куче, на который указывает эта переменная. Исправление заключается в удалении amp;
:
memcpy(buffer, base offset, size);
В противном случае ваш код в порядке.
ОБНОВЛЕНИЕ: не забудьте free()
вернуть буфер, чтобы выделенная память не «утекала» 🙂