2010-03-26 39 views
-1

指针我有一个函数:看跌期权(c)中

char *make_text(void) 
{  
     char txt[MAXLEN]; 
     //make something 
     return txt; 
} 

那是我的主要程序:

int main(void) 
{ 
     char *s = make_text(); 
     puts(s); 
     getch(); 
     return 0; 
} 

puts(s)回报0和其分毫打印。发生了什么?

回答

3

您在make_text函数中分配的内存在make_text的末尾被释放。所以你不应该尝试访问它。

你可以使用malloc或calloc分配内存,所以它不会自动释放。

1

返回一个指向堆栈值的指针是一个坏主意,并且可能不起作用。

+0

我很惊讶编译器并没有警告你,实际上。 – 2010-03-26 20:41:14

1

make_text返回txt,它被分配在make_text函数的本地存储中。当make_text返回时,该函数的本地存储中的内容被清除。要做到这一点,你需要使用动态存储与malloc():与malloc()分配

char *make_text(void) 
{ 
    char *txt = malloc(MAXLEN); 
    // do stuff 
    return txt; 
} 

内存不函数返回时消失。这意味着C不知道何时可以安全地释放内存,因此当你完成它时,你必须调用free()txt来手动释放内存。否则,你会有内存泄漏。

0

当你声明char txt [MAXLEN];在一个范围内,在这种情况下,函数make_text,char的向量txt将仅在make_text生命周期中有效。您将不得不使用动态分配。

char *make_text(void) 
{  
     char *txt = (char *) malloc(sizeof(char) *MAXLEN); 
     //make something 
     return txt; 
} 

然后,你将不得不解除分配的内存已经使用的文本后:

char *s = make_text(); 

free(s); 
+0

我会避免使用'malloc()'的返回值并使用'sizeof(char)'。不仅仅是因为sizeof(char)== 1,而是因为如果txt变成了wchar_t,那么行就是'txt = malloc(sizeof * txt * MAXLEN)'(no cast,no'sizeof(type )''不需要改变就可以使用新类型。 – 2010-03-26 20:44:00

0

你是返回一个变量,TXT,从make_text是本地的功能。这样做的结果是未定义的,因为当函数返回时txt将超出范围。

相反,你可以传递的txt作为参数:

void make_text(char * txt) 
{  
     //make something 
     sprintf(txt,"%s","Something!"); 

} 

和主:

int main(void) 
{ 
     char s[MAXLEN]; 
     make_text(s); 
     puts(s); 
     getch(); 
     return 0; 
} 
0

自动变量(局部变量和参数来调用的函数)必须保存在某个地方。那个地方在堆栈里(或者在寄存器里,但是现在也不重要)。 下面是如何使你的程序运行一点点简化堆栈注释:

int main(void) 
{ 
// [_start+0x040 ] 
// This is just the address of some code just after the code that called main. 
// You immediatly call make_text, so lets go there. 
    char *make_text(void) 
    { 
// [_start+0x040, main+0x004] 
// this is the address within main that make_text returns to 
     char txt[MAXLEN]; 
// [_start+0x040, main+0x004, txt[MAXLEN-1], ..., txt[0] ] 
     return txt; 
// This empties this function's data and pops the return address into 
// the instruction pointer. 
    } 
    char *s = make_text(); 
// [_start+0x040, &txt[0] ] 
// Now, back in main we have an address to something that is not on the stack 
// anymore. 
// Random things happen to memory that used to be part of the stack. 
     puts(s); 
// [_start+0x040, &txt[0], main+0x008 ] 
// puts() here tries to print a string containing random data which also happens 
// to be the same memory that puts is trying to use as its local variables. 
     getch(); 
// getch() is the only part that probably worked 
0

你可以返回一个指针到一个静态变量,如:

char *make_text(void) 
{  
     static char txt[MAXLEN]; 
     //make something 
     return txt; 
} 

(当然上面的代码不是线程) 。