3

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

$$->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 因分段错误而失败。我错过了什么?

任何帮助将不胜感激!

4

4 回答 4

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

那是无效的。当您显示它之前的行constant实际上是一个指针时,您不能将其视为 type int。它们不一定具有相同的 sizeof 和对齐方式。使用用于void*. 它将正确输出内存地址:

printf("->%p\n", (void*)$$->desc.constant); //LINE B
于 2008-12-06T17:22:45.403 回答
1
  1. 总是检查malloc的返回值。
  2. sprintf->snprintf
  3. "%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
于 2008-12-06T18:47:33.767 回答
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
于 2008-12-06T18:15:07.093 回答
0

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

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

你已经证明了$$->desc.constant指向同一个地方,但是你没有说明这个空间是如何分配的。然后,您在 中分配字符串空间$$->desc.constant->base.id,而没有为 . 明确分配空间base

于 2008-12-06T23:04:52.827 回答