奇怪的指针问题

时间:2010-10-13 09:53:32

标签: c pointers

下面给出的代码段编译,运行时给出结果:

$ make
gcc -g -Wall -o test test.c
$ ./test
string

/ * code1 * /

#include<stdio.h>
char *somefunc1()
{
   char *temp="string";
   return temp;
}
int main(int argc,char *argv[])
{
   puts(somefunc1());
   return 0;
}

虽然对此代码略有修改会产生不同的结果:

$ make
gcc -g -Wall -o test test.c
test.c: In function ‘somefunc1’:
test.c:5: warning: function returns address of local variable
$ ./test

/* code 2 */

#include<stdio.h>
char *somefunc1()
{
   char temp[] ="string";
   return temp;
}
int main(int argc,char *argv[])
{
   puts(somefunc1());
   return 0;
}

为什么会这样?

4 个答案:

答案 0 :(得分:4)

在第一个示例中,您将返回字符串文字的地址。只要程序执行,该文字就存在,因此代码是安全的。

在第二个示例中,您将创建一个(函数本地)数组,该数组初始化为包含字符串string。然后继续返回此数组的(第一个元素)的地址,但是一旦离开函数,数组就会被销毁。这是您的编译器警告您的内容。 使用从somefunc1返回的指针会导致未定义的行为,因为它不再引用现有对象。

答案 1 :(得分:4)

char *temp = "string";将创建指向字符串litteral的指针temp。该字符串文字存储在可执行代码的数据段中。它是不可变的,并且在函数返回后地址仍然有效。

char temp[] = "string";将在堆栈上分配7个字符,并将它们设置为“string”。这些是可变的字符。在您的示例中,返回的值指向在函数返回时不再有效的字符。

答案 2 :(得分:1)

退出函数后堆栈变量会丢失,因此在第二种情况下会出现“奇怪行为”。

答案 3 :(得分:-1)

当你做char * temp =“string”时; temp的内存在堆中分配并保持在那里直到执行程序。而当你做char temp [] =“string”;  内存在堆栈上分配,一旦超出范围,就会被删除或无效。在第二种情况下的程序中,一旦你在函数something1之外,返回的指针就变得无效。在第一种情况下,因为数组在堆上,所以内存不会失效。但后来你成功泄露了记忆。