Вопрос об использовании реализации realloc в коде C++

StackOverflow https://stackoverflow.com/questions/626123

  •  06-07-2019
  •  | 
  •  

Вопрос

Друзья

В нашем C++ я сейчас использую метод 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) говорит, что

Если бы вместо этого кто-то сделал

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, могу ли я использовать указатель на пустоту ???

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

Но, возможно, для C++ лучшим решением будет создание собственного mallocator, стандартного решения, основанного на функции malloc() языка C.Проверять этот, или этот.

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

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

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

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

Когда функция 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 */
}

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top