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が実際にはポインターであることを示しているため、それをタイプのように扱うことはできません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たぶん、あなたが文字列をdしてから持っている2つのコードの時間の間に?

$$->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 バイトを無償で割り当てたりするなど、さまざまな小罪があります。(それほど多くのスペースが必要になる可能性はほとんどありません。必要な場合は、浮動小数点数の指数範囲が通常 +/-308 であるため、少なくとも 100 桁多くする必要があります。 200 文字が必要なのは、信じられないほど大きな数または信じられないほど小さな数を可能にするためです。)

$$->desc.constantが同じ場所を指していることを示しましたが、そのスペースがどのように割り当てられているかを示していません。$$->desc.constant->base.id次に、 にスペースを明確に割り当てずに、 に文字列スペースを割り当てbaseます。

于 2008-12-06T23:04:52.827 に答える