簡體   English   中英

C指針混亂

[英]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
  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

也許在兩段代碼的時間之間,你有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM