C指针混乱

时间:2008-12-06 17:17:22

标签: c struct pointers segmentation-fault

我想在内存中存储一​​个字符串并稍后阅读:

$$->desc.constant->base.id =  (char*)malloc(200);
sprintf($$->desc.constant->base.id, "%f", $1);
printf("->%s\n", $$->desc.constant->base.id); //LINE A
printf("->%i\n", $$->desc.constant); //LINE B

//SOME OTHER CODE

//Then, later on in a function call:

printf("%i", expr->desc.constant); // LINE D
printf("%s", expr->desc.constant->base.id); // LINE C

虽然B行和D行显示相同的地址,但Line C中的printf失败并出现Segmentation故障。我错过了什么?

真的很感激任何帮助!

4 个答案:

答案 0 :(得分:9)

printf("->%i\n", $$->desc.constant); //LINE B

这是无效的。当您在它之前显示constant实际上是指针的行时,您不能将其视为int类型。它们并不具有相同的尺寸和对齐方式。使用void*使用的格式。它将正确输出内存地址:

printf("->%p\n", (void*)$$->desc.constant); //LINE B

答案 1 :(得分:1)

  1. 始终检查malloc的返回值。
  2. sprintf - > snprintf
  3. "%f" - > "%.*g"
  4. 以下是一个例子:

    /** $ gcc print_number.c -o print_number */
    #include <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(int argc, char *argv[])
    {
      const char* number_format = "%.*g";
      const int ndigits = 15;
      assert(ndigits > 0);
      const int maxlen = ndigits + 8 /* -0.e+001, Infinity */ + 1 /* '\0' */;
    
      char *str = malloc(maxlen);
      if (str == NULL) {
        fprintf(stderr, "error: malloc\n");
        exit(1);
      }    
    
      double number = 12345678901234567890.123456789012345678901234567890;
      /** `number = 0/0` crashes the program */;
    
      printf("number: %f\t", number);
    
      int len_wouldbe = snprintf(str, maxlen, number_format, ndigits, number);
      assert(len_wouldbe < maxlen);
    
      printf("%s\n", str);
      return 0;
    }
    

    输出:

    number: 12345678901234567000.000000 1.23456789012346e+19
    

答案 2 :(得分:0)

也许在free字符串后的两段代码的时间之间?

$$->desc.constant->base.id =  (char*)malloc(200);
sprintf($$->desc.constant->base.id, "%f", $1);
printf("->%s\n", $$->desc.constant->base.id); //LINE A
printf("->%i\n", $$->desc.constant); //LINE B

//SOME OTHER CODE
// which happens to do
free($$->desc.constant->base.id);

printf("%i", expr->desc.constant); // LINE D
printf("%s", expr->desc.constant->base.id); // crash

答案 3 :(得分:0)

鉴于该程序正在产生分段错误,我认为问题很可能是expr->desc.constant指定(指向)的结构已被重用,因为空间已分配,或者可能空间从未真正完全分配。

代码展示了各种静脉罪,例如使用sprintf()代替snprintf(),并且无偿地为浮点数的字符串表示分配200个字节。 (你不太可能需要那么多空间;如果你这样做,你应该最多允许至少100个数字,因为浮点数的指数范围通常为+/- 308,这是你唯一的原因'需要200个字符才能允许非常大或非常小的数字。)

您已显示$$->desc.constant指向同一位置,但您尚未显示该空间的分配方式。然后,您在$$->desc.constant->base.id中分配字符串空间,而没有明确分配base的空间。