将字符串从char指针复制到char指针

时间:2012-09-18 03:55:23

标签: c++ pointers

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

4 个答案:

答案 0 :(得分:7)

  1. 实现定义(通常只读)内存。 [Ref 1]
  2. 只要您不修改源字符串文字,就不需要这样做。
  3. 如果您将内存分配给p_one,那么它将指向新分配的内存区域,字符串文字可能/可能不会保留在内存中,但保证在程序的整个生命周期内都是活动的.string文字具有静态持续时间。 [Ref 2]
  4. 没有。用户有责任确保这一点。
  5. 好读:
    [参考1] What is the difference between char a[] = ?string?; and char *p = ?string?;?
    [参考2] "life-time" of string literal in C

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

按顺序回答所有问题

  1. 您的char指针总是存储在堆栈中。 记住,即使您正在使用内存分配,它也只是用于确定字符串的长度并附加' \ 0'字符。
  2. 根据你提到的代码,这将是一个解决方案:

    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

答案 3 :(得分:0)

如果代码中有字符串文字,则需要将其视为临时常量值。当然,您已将其分配给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 );