首页 文章

数组和指针:分段错误

提问于
浏览
0

我正在玩数组和指针,并得到这个分段错误 . 当我在代码中将“p”指针移动到“ptr”指针下方时,任何人都可以解释为什么我在这段代码中出现了这个分段错误,当我注释掉printf语句之一时,它会消失:

typedef struct str{
   char* ptr;
  }str_t;

copy(str_t t){
   char a[12];
   char *p;   //  <------ no error when move below ptr pointer 
   char *ptr;

   printf("t= %s p = %d ptr = %d\n", t, p, ptr);

   strcpy(a, t.ptr);
   printf("a = %s %u\n", a, &a);

   strcpy(ptr, t.ptr);
   printf("ptr = %s %u\n", ptr, &ptr); //<--- comment it error disappears

   p= t.ptr;
   printf("p = %s %u",p, &p);  //<--- comment it error disappears
 }

int main ()
{
  str_t t;
  char app[] = "hello";
  char ap[] ="world";

  t.ptr = ap;
  copy(t);

  printf("%s\n", app);

  return 0;
}

你可以在这里编译代码来查看结果:http://codepad.org/Q7zS8NaC

谢谢你访问这个问题 .

2 回答

  • 5

    strcpy 不在指针 p 处分配空间来存储字符串 . 您需要将其声明为数组或使用 malloccalloc 分配空间 .

    试试这个:

    int len = strlen (t.ptr);         // find length of string
    
     char * ptr = calloc (len + 1, 1); // allocate space for ptr
     if (!ptr) return;                 // error check calloc
     strcpy (ptr, t.ptr);              // copy the string
    
     char * p = calloc (len + 1, 1);   // do the same thing for p
     if (!p) return;
     strcpy (p, t.ptr);
    

    这将解决您的分段错误 .

    但是你还有一些错误,主要是格式问题 .

    • %u 打印无符号整数 . 看起来您正在尝试打印指针,因此请改用 %p .

    • printf("t= %s p = %d ptr = %d\n", t, p, ptr); 完全错了 .

    • 您需要引用 t 的成员,即 t.ptr

    • p 是指针,不是整数 . 使用 %p 而不是 %d

    • ptr 也是一个指针 . 使用 %p%s

    如果您不确定格式,请阅读 printfdocumentation . 事实上,阅读任何功能的文档,如果你不确定如何使用它 - 你会省去很多麻烦 .

  • 2

    您的代码有几个未定义的行为:

    • 第一个 printf 使用 %d 说明符打印指针

    • 第二次调用 strcpy 调用尝试写入未初始化指针指向的内存

    • printf 的第二次和第三次调用将指向数组的指针传递给格式说明符 %u

    删除其中一个指针会导致代码崩溃,但由于存在未定义的行为,代码无法正常运行,并且可能随时崩溃 .

    这是修复它的一种方法:

    char a[12];
    char *p;
    char *ptr;
    
    printf("t= %s p = %x ptr = %x\n", t.ptr, (void*)p, (void*)ptr);
    
    strcpy(a, t.ptr);
    printf("a = %s %x\n", a, (void*)(&a[0]));
    ptr = malloc(strlen(t.ptr)+1);
    // In production, check ptr for NULL
    strcpy(ptr, t.ptr);
    printf("ptr = %s %x\n", ptr, (void*)&ptr);
    
    p= t.ptr;
    printf("p = %s %x", p, (void*)&p);
    // Release the memory when you are done
    free(ptr);
    

相关问题