Чтение блока памяти в C

#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() вернуть буфер, чтобы выделенная память не «утекала» 🙂