0
char * p_one = "this is  my first char pointer";
char * p_two= "this is second";
strcpy(p_one ,p_two);

考虑上面的代码。这给出了访问冲突错误。所以请帮助理解

  1. 当前"this is my first char pointer"字符串存储在内存中的什么位置?堆或栈
  2. 为什么我需要在调用之前为 p_one 分配内存strcpy,即使它已经存储了第一个字符串。为什么"this is second"字符串不能复制到同一位置?
  3. 如果我在调用之前为 p_one 分配内存,那么 p_one指向的字符串strcpy会发生什么?"this is my first char pointer"它会留在记忆中吗?
  4. 如何strcpy知道特定指针是否已分配内存?
4

4 回答 4

7
  1. 实现定义的(通常是只读的)内存。[参考 1]
  2. 只要您不修改源字符串文字,就不需要这样做。
  3. 如果将内存分配给p_one,那么它将指向新分配的内存区域,字符串文字可能/可能不会留在内存中,但它保证在程序的整个生命周期内都处于活动状态。字符串文字具有静态持续时间生命周期。[参考 2]
  4. 它没有。用户有责任确保这一点。

好读:
[Ref 1] char a[] = ?string?; 之间有什么区别?和 char *p = ?string?;?
[参考 2] C 中字符串文字的“生命周期”

于 2012-09-18T03:56:55.940 回答
1

首先,您的编译器应该警告 p_one 和 p_two 实际上是const char *因为编译器在编译时分配了该字符串的存储空间。

您无法修改它们的原因是因为理论上您可以在它们之后覆盖内存,这就是导致使用 stackoverflow 进行黑客攻击的原因。

编译器也可能很聪明,并意识到你在 10 个地方使用了这个字符串,但注意到它是相同的,所以从一个地方修改它会改变它——但这会破坏其他 9 个使用它的地方的逻辑

于 2012-09-18T04:00:43.643 回答
1

按顺序回答所有问题

  1. 您的 char 指针始终存储在堆栈中,这有点直截了当。请记住,即使您正在使用内存分配,它也仅用于确定字符串的长度并附加 '\0' 字符。

根据您提到的代码,这将是一种解决方案:

int main()
{
   char * p_one = "this is  my first char pointer";
   char * p_two= "this is second";
   size_t keylen=strlen(p_two);
   p_one=(char *)malloc(keylen*sizeof(char));
   strncpy(p_one ,p_two,strlen(p_one));
   printf("%s",p_one);

   return 0;
}
  1. 当您声明一个 char 指针时,它仅指向内存分配。所以字符串复制不指向字符的结尾。因此,在这种情况下,最好使用 strncpy。

  2. 是的,它正在分配内存。

  3. 强制转换 malloc 的结果是一种不好的做法,因为您将抑制可能引发的运行时错误,感谢 Gewure
于 2016-05-24T04:53:32.850 回答
0

当您的代码中有这样的字符串文字时,您需要将其视为临时常量值。当然,您将其分配给 a char*,但这并不意味着您可以修改它。C 规范中没有任何内容表明这是合法的。

另一方面,这没关系:

const size_t MAX_STR = 50;
char p_one[MAX_STR] = "this is  my first char pointer";
const char *p_two = "this is second";
strcpy( p_one, p_two );
于 2012-09-18T04:03:28.803 回答