Есть ли способ очистить буферный элемент за элементом? - PullRequest
0 голосов
/ 25 августа 2010

В моем коде есть строка "fread", которая читает содержимое файла следующим образом

  fread(buffer,sizeof(char),1024,file1);

Я знаю, что могу освободить буфер, используя free(buffer);, но мои вопросы: есть ли способ удалить элементы в буфере по одному? Скажем, я использовал первый элемент, и он мне больше не нужен, поэтому я хочу удалить его. Что-то, что может сделать это

for(i=0 ; i< 1024; i++){
   *do something with buffer[1] *
   free(buffer[1]); // I know this is wrong but something which can do the same.
 }

Спасибо, Сунил

Ответы [ 5 ]

1 голос
/ 25 августа 2010

Вы можете освободить только то, что вы выделили. Вы выделили весь буфер, а не отдельные элементы буфера.

из N1256 (у меня нет с собой стандарта C99)

$ 7.20.3.2 / 2- "Свободная функция заставляет освободить пространство, на которое указывает ptr, то есть сделать доступным для дальнейшего выделения. Если ptr является нулевым указателем, никаких действий не происходит. В противном случае, если аргумент не соответствует указателю, ранее возвращенному функцией realloc из calloc, malloc или 261), или если пространство было освобождено при вызове free или realloc, поведение не определено.

Однако, если вы хотите удалить ненужные элементы, считанные из буфера, вам придется либо сделать это самостоятельно, если вы используете массивы, либо вам придется согласиться на контейнеры STL (вектор / список) и т. Д. (Которые предоставляют интерфейсы для управления элементами)

1 голос
/ 25 августа 2010

Нет, нет способа сделать это. Просто сохраните оригинальный указатель где-нибудь и увеличьте указатель, с которым вы работаете. Когда вы закончите, вы можете free исходный указатель.

Тем не менее, если вы используете C ++, вы не должны использовать malloc или free вообще, и при этом вы не должны использовать fread ....

1 голос
/ 25 августа 2010

Если вы хотите разбить ваше распределение / чтение файла на меньшие значения, вы можете сделать это. Как сказал Стив, вы можете освободить только те же самые фрагменты памяти, которые вы выделяете.

Пример изменения существующего кода:

const size_t size_of_full_buffer = 1024;
const size_t size_of_buffer_chunk = 128; /* evenly divisible */
size_t size_read = 0;

while(size_read <= size_of_full_buffer)
{
  buffer = (char*) malloc(sizeof(char) * size_of_buffer_chunk)
  fread(buffer, sizeof(char), size_of_buffer_chunk, file1);

  for(i = 0; i < size_of_buffer_chunk; i++)
  {
      /* do something with buffer[1] */
  }

  free(buffer);
  size_read += size_of_buffer_chunk;
}

Однако вы должны использовать поток входных файлов вместо fread. Если файловые потоки требуют от вас выделения буфера (они могут и не быть), используйте вектор вместо malloc / free.

  • std :: fstream, std :: ifstream
  • станд :: вектор
1 голос
/ 25 августа 2010

Буфер должен быть освобожден так же, как он выделен, за один выстрел.Вы запросили непрерывный блок памяти, который возвращается вам с предисловием информации управления кучей, описывающей буфер как таковой.Если вы попытаетесь освободить элементы по отдельности, менеджер кучи запутается, и произойдет сбой процесса.

0 голосов
/ 25 августа 2010

C ++ stl способ сделать это будет

#include <fstream>
#include <cassert>
#include <vector>

void foo () {
   const char* myFilename = "some_file_path"; 
   std::ifstream myStream (myFilename);

   assert (myStream.is_open());

   int n = 1024;
   std::vector<char> buffer (n);
   myStream.read (&buffer[0], n);
   assert (myStream.good());

   for (int i = 0; i < n; i++) {
       char* myPtr = &buffer[i];
       //do something with buffer[i]
   }

}
...