C ++堆栈内存未被释放

时间:2013-06-23 05:42:35

标签: c++ c pointers memory-management

请考虑以下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;
}

我认为在函数名()中分配用于存储“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 *的行为有区别?

4 个答案:

答案 0 :(得分:1)

字符串文字"JUSTFORFUN" 存储在堆栈中 - 它具有静态存储持续时间。尽管只出现在函数name中,但字符串文字本身该函数是本地的(没有字符串文字 - 它们都有静态存储持续时间)。

因此,第一个程序的行为实际上已经很好地定义了。 name返回后,val包含具有静态存储持续时间的字符串文字的地址,然后打印。

在第二个程序中,您将返回函数本地的int的地址。函数返回后,int不再存在,因此使用它会产生未定义的行为 - 在典型情况下,它可能会打印出该地址当前位的任何值,但不能保证它会做什么。

答案 1 :(得分:1)

“JUSTFORFUN”未在堆栈上分配。它与程序的其余静态数据一起存储。 name函数在堆栈上存储指针。该指针指向静态数据。

然而,你的int 存储在堆栈中。您的nameint函数返回指向堆栈上该位置的指针。做这样的事情会导致你的程序很快崩溃。

答案 2 :(得分:0)

两种不同的情况:

在字符串的情况下,您没有分配任何内存,因为像const char* x = "sdfsdf"这样的原始字符串保存在可执行文件的.data部分中,因此您可以将其视为一个静态不可变数据,该数据加载了程序(根本没有内存分配!)

在第二种情况下,val在函数堆栈上分配,然后在函数返回时变为无效。

答案 3 :(得分:0)

  

我认为在函数名()中分配用于存储“JUSTFORFUN”的内存是在堆栈上分配的

不,不是。字符串文字隐含地具有static存储持续时间。他们的一生就是该计划的一生。没有delete,您的第一个程序是正确的。

  

引发错误“未释放指针被释放”

当然可以,因为您没有使用new创建该对象。

  

为什么intchar *的行为之间存在差异?

因为这就是语言的定义方式。在第二个程序中,int 执行具有自动存储持续时间(它是用您的单词分配的“堆栈”),因此使用其封闭范围之外的地址(这是此处的函数)调用未定义的行为。