Вопрос об использовании реализации realloc в коде C ++ - PullRequest
2 голосов
/ 09 марта 2009

Друзья

В нашем C ++ Iam использует метод realloc для изменения размера памяти, выделяемой malloc. Использование realloc () выполняется так, как показано ниже

my_Struct *strPtr =(my_struct*)malloc(sizeof(my_Struct));

/* an later */

strPtr = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);

сейчас Википедия (_ http://en.wikipedia.org/wiki/Malloc)says, что

Если вместо этого один

void *p = malloc(orig_size);

/* and later... */

p = realloc(p, big_size);

тогда, если невозможно получить байты памяти big_size, p будет иметь значение NULL, и у нас больше не будет указателя на память, ранее выделенную для p, что приведет к утечке памяти

И это также говорит о том, что правильный способ исправить вышеуказанную ошибку -

void *p = malloc(orig_size);

/* and later... */

void *tmp = realloc(p, big_size); 

if (tmp != NULL)
 {

p = tmp; /* OK, assign new, larger storage to p */

} 

else 

{

/* handle the problem somehow */

}

Можете ли вы сказать мне, какой лучший способ использовать realloc ()

также, если у меня есть указатель на структуру, а затем при использовании realloc позже я могу использовать указатель на пустоту ???

Большое спасибо

Ответы [ 6 ]

7 голосов
/ 09 марта 2009

Конечно, вы должны защищать от случая, когда realloc() возвращает NULL. Это выделение памяти, и в C (где realloc()) в основном используется, я думаю, что программисты на C ++ думают, что это немного низкоуровневый / qaint, чтобы использовать необработанные realloc() вызовы, выделения памяти всегда могут дать сбой.

Непосредственная перезапись указателя возвращаемым значением является ошибкой, поскольку в этом случае исходный указатель удаляется и происходит утечка памяти в случае сбоя перераспределения.

5 голосов
/ 09 марта 2009

Malloc () и realloc () являются C-функциями. На самом деле, realloc () выполняет malloc () и free () в зависимости от передаваемых аргументов:

  • Если вы передадите ему нулевой указатель, realloc сделает то же, что и malloc.
  • Если вы передадите ему нулевой размер, realloc сделает то, что бесплатно.

Цитируется из Здесь , где у вас есть более глубокое объяснение.

Библиотека C делает невозможным расширение блока памяти на месте, поэтому C ++ также не поддерживает его.

Если вы хотите придерживаться функций C, то вы должны удерживать указатель вашего первого выделения памяти при вызове realloc (). Затем вы проверяете, имеет ли он значение NULL, в противном случае вы присваиваете его так же, как в своем последнем коде.

Но, возможно, для C ++ лучшее решение - создать свой собственный mallocator, стандартное решение, основанное на malloc () в C. Отметьте это или это .

1 голос
/ 09 марта 2009

Используйте предложенный подход - удерживайте указатель на предыдущий буфер до тех пор, пока realloc не вернется успешно. После того, как realloc () успешно вернет, предыдущий блок был освобожден, и все указатели на него стали висящими - настройте их.

realloc, так же как и malloc, не заботится о типе указателя - вы можете использовать void *, а также что угодно *.

0 голосов
/ 09 марта 2009

Почему вы используете malloc и realloc? В C ++ почти всегда есть лучший способ.

Если вы используете его для создания массивов переменной длины, вам почти наверняка лучше использовать std :: vector <> или, возможно, один из других контейнерных шаблонов.

Если вы используете вместо этого C, возможно, с компилятором, поддерживающим C ++, то правильный способ - второй метод, который не теряет весь блок памяти, когда не удается выделить.

Ответ на ваш второй вопрос также зависит от того, используете ли вы C или C ++. В C void * - это типовой указатель данных, который можно преобразовать свободно. В C ++ void * должен быть явно преобразован. Если вы на самом деле пишете C, вам нужно использовать malloc () и друзей, которые работают с void *. Если вы действительно пишете C ++, вам нужно привести его, что делает его более неловким. Ни в том, ни в другом случае realloc () не работает с указателями на структуру, а с указателями на void.

0 голосов
/ 09 марта 2009

Когда realloc () завершается с ошибкой и возвращает NULL, исходная память остается неизменной.
Поэтому вы должны использовать это так:

my_Struct* strPtr =(my_struct*)malloc(sizeof(my_Struct));

/* an later */

my_Struct* tmp = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);
if (tmp != NULL)
{
    strPtr = tmp;
}
else
{
    /* realloc Failed. Need to do something */
}
0 голосов
/ 09 марта 2009

Как и другие говорили, просто используйте realloc как предложено.

Но «способ C ++» в этом заключается в том, чтобы использовать std :: vector <> вместо того, чтобы поддерживать массивы самостоятельно. Таким образом, стандартная библиотека C ++ позаботится о низкоуровневых деталях перераспределения (предположительно с использованием realloc ()).

...