[英]C Pointer confusion
我想在内存中存储一个字符串并稍后阅读:
$$->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失败并出现Segmentation故障。 我错过了什么?
真的很感激任何帮助!
printf("->%i\n", $$->desc.constant); //LINE B
那是无效的。 当你在它之前显示该行constant
实际上是一个指针时,你不能把它当作int
类型来对待它。 它们并不具有相同的尺寸和对齐方式。 使用用于void*
的格式。 它将正确输出内存地址:
printf("->%p\n", (void*)$$->desc.constant); //LINE B
malloc
的返回值。 sprintf
- > snprintf
"%f"
- > "%.*g"
这是一个例子:
/** $ 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
也许在两段代码的时间之间,你有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
的空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.