您的程序在语法上是有效的 C++,但它会产生未定义的行为,因为您将堆栈对象的地址传递给堆分配器。通常这意味着您的程序在执行时会崩溃。
堆栈和堆是分配给执行程序的进程的两个不同的内存区域。当你输入一个函数来保存它的参数和局部变量时,堆栈会增长,当你从函数返回时它会自动收缩。另一方面,堆是一个单独的地址区域,可以按需获取内存,并且在不再需要时必须显式释放。
如果将局部变量的地址传递给 realloc(),它可能会尝试释放其内存并将其分配到其他地方。由于地址不是来自堆,而 realloc() 在堆上操作,这将失败。realloc() 很可能会检测到地址不是来自堆并中止程序。
除此之外,示例程序包含一些逻辑错误。
char myString = NULL;
您声明一个变量来保存一个字符,而不是一个字符串。C 风格的字符串具有 type char*
,即指向 char 的指针。
此外,char 被分配NULL
,通常分配给无效指针的地址为零。这是编译的,因为预处理器替换NULL
为文字0
。实际上,您在 char 中存储了一个零字节,按照惯例,它也是 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;
}