2013-06-23 178 views
-2

请考虑以下C++代码片段。我将一个char *引用作为参数传递给一个函数。C++堆栈内存未被释放

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 *的行为有区别?

+1

“我认为在函数名()中分配用于存储”JUSTFORFUN“的内存被分配到堆栈上。” - 不是。 – Mat

+0

@Mat - 请参考:http://stackoverflow.com/questions/51592/is-there-a-need-to-destroy-char-string-or-char-new-char6 – Mishra

+1

这并不是说在任何地方字符串被分配在堆栈上。它不是,它是一个全局的(可能存储在一个只读部分)。 – Mat

回答

1

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

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

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

1

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

您的int,但是,存储在堆栈上。你的nameint函数返回一个指向栈上那个位置的指针。做这样的事情可能会导致程序崩溃很快。

0

两种不同的情况:

在字符串的情况下,因为像const char* x = "sdfsdf"原始字符串保存在可执行文件的.data节,所以你可以把它作为一个静态不变的数据你没有分配任何内存(根本没有内存分配分配)

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

0

我认为()分配给在函数名存储“JUSTFORFUN”内存堆栈

没有上分配,事实并非如此。字符串文字隐含地具有static存储持续时间。他们的一生就是这个节目。没有delete,你的第一个程序是正确的。

抛出“被释放的指针是未分配”的错误

当然有,是因你没有创建使用new该对象。

为什么intchar *的行为有差异?

因为这就是语言的定义。在第二个程序中,int确实有有自动存储持续时间(它与您的文字是“堆栈分配”),因此在其封闭作用域(这是此处的函数)外使用其地址会调用未定义的行为。