C指针混乱

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

$$->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显示相同的地址,但线路C中的printf失败并出现分段故障。 我错过了什么?

真的很感激任何帮助!

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

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

 printf("->%p\n", (void*)$$->desc.constant); //LINE B 
  1. 总是检查malloc的返回值。
  2. sprintf – > snprintf
  3. "%f" – > "%.*g"

这是一个例子:

 /** $ gcc print_number.c -o print_number */ #include  #include  #include  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 

也许在两段代码的时间之间,你有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 

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

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

您已经显示$$->desc.constant指向同一个地方,但您尚未显示该空间的分配方式。 然后在$$->desc.constant->base.id分配字符串空间,而不清楚地为base分配空间。