字符串常量存储

时间:2012-05-07 11:31:12

标签: c

以下两个函数之间是否存在任何差异,两种情况下都没有返回局部变量的地址,但是使用f1()fn会返回正确的值4而不是f2()。同样在第三种情况下,我正确的是,字符串常量不存储在堆栈中,因此当我们返回指针时它将正常工作。那么存储字符串常量的位置是什么?

int* f1()
{
  int* a=(int*)4;
  return a;
}

int* f2()
{
  int a=4;
  return &a;
}

char* f3()
{
  char* p="abcd";
  return p;
}

3 个答案:

答案 0 :(得分:6)

所有这些之间存在差异:

  1. 第一个返回int *,其值为4,请注意它不指向值为4的变量,而是指向地址4.
  2. 第二个返回指向保存4的变量的指针,但实际上,该指针无效,因为它指向已返回函数的局部变量,并且对它的任何使用都将导致未定义的行为。
  3. 第三个返回一个指向char的指针(根据定义),但实际上这是一个指向字符串文字的指针(通过实现)。它的问题在于,当函数返回char *而不是const char *时,可能会尝试修改返回缓冲区,这将再次导致未定义的行为。

答案 1 :(得分:1)

  • f1将值4转换为地址,实际上指向内存中的某个位置。
  • f2返回局部变量的地址。取消引用此指针将是未定义的行为。
  • f3是指向字符串文字的指针。这是一个有效指针,因为字符串文字的生命周期与程序生命周期(静态存储持续时间)相同。存储的确切位置由实现定义。操作字符串文字的内容是未定义的行为。

答案 2 :(得分:0)

  • f1中,您已明确指定地址4并返回相同的地址,而不是该地址的值。
  • 局部变量在堆栈上分配,因此在返回f2的{​​{1}}中,您将返回堆栈上的地址,而不是内存中该地址的&a。当函数从堆栈中清除时,取消引用此地址会导致未定义的行为。
  • 字符串文字分配在只读数据部分,并注意

    之间的区别

    4char arr[]="abcd";

    第一个是字符数组,在堆栈上分配,而第二个是指向字符串文字的指针(字面值不是指针)在只读数据部分分配。

PS:我在这里假设了GCC / x86。