C 指针混乱

发布于 2024-07-09 06:43:50 字数 528 浏览 6 评论 0原文

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

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

任何帮助将不胜感激!

I want to store a string in memory and read it later:

$->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

Although Line B and Line D show the same address, the printf in Line C fails with a Segmentation fault. What am I missing?

Any help would really be appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

时常饿 2024-07-16 06:43:50
printf("->%i\n", $->desc.constant); //LINE B

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

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

That is invalid. As you show the line prior to it that constant is actually a pointer, you cannot treat it as if it were of type int. They don't necassarily have the same sizeof and alignment. Use the format used for void*. It will output memory addresses properly:

printf("->%p\n", (void*)$->desc.constant); //LINE B
负佳期 2024-07-16 06:43:50
  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
  1. always check malloc's return value.
  2. sprintf -> snprintf
  3. "%f" -> "%.*g"

Here's an example:

/** $ 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;
}

Output:

number: 12345678901234567000.000000 1.23456789012346e+19
街角迷惘 2024-07-16 06:43:50

也许在两段代码之间,您已经释放字符串了?

$->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

Maybe between the time of the two pieces of code you have since freed the string?

$->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
残疾 2024-07-16 06:43:50

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

该代码表现出各种小罪,例如使用 sprintf() 而不是 snprintf(),以及无缘无故地为浮点数的字符串表示分配 200 个字节。 (您不太可能需要那么多空间;如果您这样做,您很可能应该比您拥有的数字多至少 100 位,因为浮点数的指数范围通常为 +/-308,并且您这样做的唯一原因是需要 200 个字符才能允许令人难以置信的大或令人难以置信的小数字。)

您已经表明 $$->desc.constant 指向同一个地方,但您没有表明该空间如何被分配。 然后,您在 $$->desc.constant->base.id 中分配字符串空间,而无需明确为 base 分配空间。

Given that the program is producing a segmentation fault, I think the problem is most likely that the structure designated (pointed to) by expr->desc.constant has been reused since the space was allocated, or possibly the space was never really allocated at all.

The code exhibits various venial sins, such as using sprintf() instead of snprintf(), and gratuitously allocating 200 bytes for the string representation of a floating point number. (You are very unlikely to need that much space; if you do, you should most probably allow for at least 100 more digits than you have, since the exponent range for floating point numbers is usually +/-308, and the only reason you'd need 200 characters is to allow for incredibly large or incredibly tiny numbers.)

You have shown that $$->desc.constant points to the same place, but you have not shown how that space is allocated. You then allocate the string space in $$->desc.constant->base.id, without clearly allocating the space for base.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文