Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将指向堆栈变量的指针传递给realloc()是否有效?_C++_C_Memory_Memory Management_Heap Corruption - Fatal编程技术网

C++ 将指向堆栈变量的指针传递给realloc()是否有效?

C++ 将指向堆栈变量的指针传递给realloc()是否有效?,c++,c,memory,memory-management,heap-corruption,C++,C,Memory,Memory Management,Heap Corruption,看起来很好,但我仍然对堆栈和堆有点困惑。允许这样做吗?如果允许,是否需要手动释放myString,还是在超出范围时释放 编辑:谢谢你的回复,所以我认为这同样是非法的 int main() { char myString = NULL; realloc(&myString, 5); strncpy((char *)&myString, "test", 5); } 这不应该起作用。你在重新分配一些一开始就不是malloced的东西。不,当它超出范围时,它不会被释

看起来很好,但我仍然对堆栈和堆有点困惑。允许这样做吗?如果允许,是否需要手动释放
myString
,还是在超出范围时释放


编辑:谢谢你的回复,所以我认为这同样是非法的

int main()
{
   char myString = NULL;
   realloc(&myString, 5);
   strncpy((char *)&myString, "test", 5);
}

这不应该起作用。你在重新分配一些一开始就不是malloced的东西。不,当它超出范围时,它不会被释放-当您使用malloc或realloc时,一切都取决于您

更新:你的编辑没有改变任何东西-你仍然在尝试重新定位一些一开始没有被malloced的东西。此外,您不能忽略realloc的返回值-如果realloc必须将内存移动到其他地方,您将在返回中找到它。换言之:

//I want the code to change myString to "tests"
char myString[5] = "test";
realloc(&myString, strlen(myString)+2);
myString[4] = 's';
myString[5] = '\0';

在realloc之后,ptr可能指向内存中的一个完全不同的位置,继续使用ptr的原始值可能会使您使用的内存被释放,并且没有您想象的那么大。

您发布的代码存在一些问题:

  • 是的,您需要释放使用malloc、realloc和其他相关的C风格内存分配函数分配的所有内容
  • 我想你是想用char*myString,而不是char。在堆栈上传递某个内容的地址(您的字符)是完全错误的
  • 在realloc中使用myString char指针之前,需要将其初始化为NULL
  • 您应该将4传递到strncpy而不是5,如果您有一个更大的字符串,您将覆盖内存
  • 您应该释放在示例中创建的缓冲区
  • 您应该检查realloc调用的返回值。realloc()
[关于realloc的返回值:]在成功完成时 不等于0,realloc()返回一个 指向(可能已移动)的指针 分配的空间。如果大小为0,则 空指针或唯一指针 可以成功传递给 返回free()。如果没有 足够的可用内存,realloc() 返回空指针并设置errno 致[依诺门]

  • 当您传入NULL时,re-alloc将像malloc一样工作:
如果ptr是空指针,则realloc() 其行为类似于 指定的大小

<强>一个更为C++的方式:< /强>

你把它标记为C++,使用C++的新操作符更安全。尽管新操作符不允许重新分配,但它将用于分配和重新使用现有缓冲区(新位置)

甚至:

char *myString = new char[5];
strncpy(myString, "test", 4); 
//...
delete[] myString;
#包括
//...
std::string str=“test”;

不,这是完全错误的。realloc只能用于重新分配malloc分配的内存,您所做的工作只是偶然发生的,最终会导致可怕的崩溃

#include <string>

//...

std::string str = "test";

不过,使用new和delete更好,使用std::string更好

这太危险了!这将损坏堆栈。如果要在返回main()的函数堆栈上重新定位某个对象,那么实际上会覆盖堆栈帧并返回main()以外的其他位置。这是一个潜在的安全漏洞

尝试运行以下命令。如果它在realloc上崩溃,你就幸运了。使用memcpy(&myString)之类的东西可能会造成严重的损害


您不必释放
myString
,因为它位于堆栈上(离开作用域时会被“释放”)

realloc
在这里是非法的,地址必须是
NULL
或先前调用
realloc
malloc
calloc
返回的地址

您声明的每个变量都在堆栈上,甚至是一个指针:

int*x

变量
x
在堆栈上!它的类型为
指针
,包含一个地址

x=(int*)malloc(sizeof(int))


malloc
返回的地址分配给变量x!
x
的内容是一个内存地址

这是你永远不应该做的。尝试释放()或realloc()堆栈变量可能导致未定义的行为,包括(但不限于)损坏的堆栈(导致不可预测的控制流)、损坏的堆服务结构、损坏的用户内存。如果程序只是因为AV而崩溃,那你就幸运了。在某些情况下,它可能会起作用,但你永远不应该尝试这样做


经验法则:只将内存返回到分配给它的内存管理器。在这种情况下,不要尝试将stack变量返回到运行时堆。

您所做的问题是,您正在处理一些不是变量的东西。您将myString定义为char,因此正在尝试更改其地址。那太糟糕了

函数realloc()不应该更改传递给它的任何内容。它获取指向堆上某个内存的指针(如果没有分配任何内存,则为空指针),并返回指向堆上某个内存的指针

因此,您可以提供空指针或指向malloc()或realloc()或calloc()分配的对象的指针,并存储返回的指针

差不多

int dostuff();

int main()
{
        dostuff();
        return 0;
}

int dostuff()
{
        char myString = NULL;
        realloc(&myString, 5);
        strncpy((char *)&myString, "test", 5);
        return 0;
}
将工作,但您将希望释放()myString


在C++中,使用第二个代码示例:使用STD::String。

< P>:

是的,这也是违法的。myString不是用malloc(或calloc)分配的,因此不能用realloc重新分配,也不能用free释放

另外,realloc不会将指向指针的指针作为其第一个参数。它接受一个指向已分配内存的指针,并返回另一个(可能不同的)指针。改为这样编写呼叫:

char * myString = NULL;
myString = realloc(myString, 5);

<>你的程序是语法上有效的C++,但是它会产生不确定的行为,因为你把栈对象的地址传递给堆分配器。通常这意味着您的程序在执行时将崩溃

堆栈和堆
int dostuff();

int main()
{
        dostuff();
        return 0;
}

int dostuff()
{
        char myString = NULL;
        realloc(&myString, 5);
        strncpy((char *)&myString, "test", 5);
        return 0;
}
char * myString = NULL;
myString = realloc(myString, 5);
myString = realloc(myString, strlen(myString)+2);

char myString = NULL;

realloc(&myString, 5);

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;
}

#include <string>

int main()
{
   std::string myString;

   /* some code using myString */

   myString = "test";

   return 0;
}