Ваша программа синтаксически допустима на C ++, но будет вызывать неопределенное поведение, потому что вы передаете адрес объекта стека распределителю кучи. Как правило, это означает, что ваша программа будет аварийно завершена при выполнении.
Стек и куча - это две разные области памяти, выделенные процессу, выполняющему вашу программу. Стек увеличивается по мере того, как вы вводите функцию для хранения ее аргументов и локальных переменных, и автоматически сжимается при возврате из функции. Куча, с другой стороны, является отдельной адресной областью, где память может быть получена по требованию и должна быть освобождена явно, когда она больше не нужна.
Если адрес локальной переменной передается в realloc (), он может попытаться освободить свою память и выделить ее в другом месте. Поскольку адрес не из кучи, а realloc () работает в куче, это не удастся. Скорее всего, realloc () обнаружит адрес не из кучи и прервет работу программы.
Помимо этого, пример программы содержит несколько логических ошибок.
char myString = NULL;
Вы объявляете переменную для хранения символа, а не строки. Строка в стиле C имеет тип char*
, то есть указатель на символ.
Кроме того, символу присваивается NULL
, нулевой адрес, который обычно присваивается недействительным указателям. Это компилируется, потому что препроцессор заменяет NULL
на литерал 0
. На самом деле, вы храните нулевой байт в символе, который также, по соглашению, является терминатором строки в стиле C.
realloc(&myString, 5);
Как упоминалось выше, это недопустимо, потому что вы передаете адрес объекта стека распределителю кучи. Эта проблема остается в вашем втором примере кода.
Кроме того, вы отбрасываете возвращаемое значение. realloc()
возвращает адрес, на котором была выделена новая память. Это не может быть тот же адрес, что и раньше. Это может быть даже NULL, что является realloc()
способом сказать вам, что оно вышло из памяти.
strncpy((char *)&myString, "test", 5);
Это правильно, но приведение является избыточным.
Вот более правильная версия вашей программы:
#include <stdlib.h>
#include <string.h>
int main()
{
/* allocate space for, say, one character + terminator */
char* myString = (char*) malloc(2);
/* some code using myString omitted */
/* get more space */
myString = (char*) realloc(myString, 5);
/* write to the string */
strncpy(myString, "test", 5);
/* free the memory */
free(myString);
return 0;
}
В C ++ лучше полностью избегать realloc (). Например, вы можете использовать что-то вроде следующего:
#include <string>
int main()
{
std::string myString;
/* some code using myString */
myString = "test";
return 0;
}