C++ 堆栈内存没有被释放
Posted
技术标签:
【中文标题】C++ 堆栈内存没有被释放【英文标题】:C++ Stack memory not being freed 【发布时间】:2013-06-23 05:42:34 【问题描述】:请考虑以下 C++ 代码片段。我将 char * 的引用作为函数的参数传递。
void name(char **str)
*str=(char *)"JUSTFORFUN";
int main(int argc, const char * argv[])
char *test;
name(&test);
cout<<test; //Prints "JUSTFORFUN"
//delete(test); //Throws error "pointer being freed was not allocated"
return 0;
我认为分配用于在函数 name() 中存储“JUSTFORFUN”的内存是在堆栈上分配的。因此,当控件超出 name() 时,与 (char *)"JUSTFORFUN" 关联的内存应该已被编译器释放。我的问题是为什么我在打印测试时仍然得到正确的输出?它不应该打印一个垃圾值吗? 当我为 int 做类似的事情时。我得到了预期的结果。
void nameint(int **value)
int val=5;
*value=&val;
int main(int argc, const char * argv[])
int *val;
nameint(&val);
cout<<*val; //Prints a junk value 1073828160
return 0;
为什么 int 和 char * 的行为有区别?
【问题讨论】:
“我认为在函数 name() 中分配用于存储“JUSTFORFUN”的内存是在堆栈上分配的。” - 不是。 @Mat - 请参考:***.com/questions/51592/… 这并没有说字符串在堆栈上分配的任何地方。不是,它是一个全局的(可能存储在只读部分)。 @zmbq 我的直接猜测是 1. 受骗,2. 缺乏研究工作。 C++ string literal data type storage的可能重复 【参考方案1】:字符串文字"JUSTFORFUN"
不存储在堆栈中——它具有静态存储持续时间。尽管只出现在函数 name
中,但字符串文字本身对于该函数来说是非本地的(没有字符串文字是 - 它们都有静态存储持续时间)。
因此,第一个程序的行为实际上是很好定义的。在name
返回后,val
包含具有静态存储持续时间的字符串文字的地址,然后您将打印该地址。
在您的第二个程序中,您将返回函数本地的 int 的地址。函数返回后,int
不再存在,因此使用它会产生未定义的行为——在典型情况下,它可能会打印出该地址当前位的任何值,但不能保证它是什么会的。
【讨论】:
【参考方案2】:“JUSTFORFUN”未在堆栈上分配。它与程序的其余静态数据一起存储。 name
函数在堆栈上存储一个指针。该指针指向静态数据。
但是,您的 int 存储在堆栈中。您的 nameint
函数返回一个指向堆栈上该位置的指针。这样做可能会导致您的程序很快崩溃。
【讨论】:
【参考方案3】:两种不同的情况:
在字符串的情况下,您没有分配任何内存,因为像 const char* x = "sdfsdf"
这样的原始字符串保存在可执行文件的 .data 部分中,因此您可以将其视为随程序加载的静态不可变数据(根本没有内存分配!)
第二种情况val
在函数栈上分配,然后在函数返回时变为无效。
【讨论】:
【参考方案4】:我认为分配用于在函数 name() 中存储“JUSTFORFUN”的内存是在堆栈上分配的
不,不是。字符串文字隐式具有 static
存储持续时间。它们的生命周期就是程序的生命周期。没有delete
,你的第一个程序是正确的。
抛出错误“被释放的指针未被分配”
当然可以,因为您没有使用 new
创建该对象。
为什么
int
和char *
的行为有区别?
因为这就是语言的定义方式。在第二个程序中,int
确实 具有自动存储持续时间(用您的话来说是“堆栈分配”),因此在其封闭范围之外使用它的地址(这是这里的函数)会调用未定义的行为.
【讨论】:
以上是关于C++ 堆栈内存没有被释放的主要内容,如果未能解决你的问题,请参考以下文章