2012-01-30 29 views
5

這裏我想創建動態內存。 這裏我知道輸出大小,我想打印while循環後的最後輸出。Realloc中出現分段錯誤

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void main() { 

    char *sdpCommand = "sdptool browse 04:18:0F:B1:48:B5"; 

    FILE *fp; 
    fp = popen(sdpCommand, "r"); 

    char *results = 0; 
    if (fp == NULL) { 
     printf("Failed to run command\n"); 
     return; 
    } 

    char* buffer = malloc(514); 
    while (fgets(buffer, strlen(buffer) - 1, fp) != NULL) { 
     realloc(results, strlen(results) + strlen(buffer)); 
     memcpy(results + strlen(results), buffer, strlen(buffer)); 
    } 
    printf("Output ::: %s", results); 

    /* close */ 
    pclose(fp); 
    sleep(1); 

} 

回答

11

主要有兩個問題:

  1. realloc()回報新地址:

    new_results = realloc(results, ...); 
    if (new_results != NULL) { 
        results = new_results; 
    } else { 
        /* handle reallocation failure, `results' is still valid */ 
    } 
    
  2. sizeof()不是找出results大小和正確的方式的buffer。它只會返回指針的大小。對於results,您可能希望自己跟蹤分配的大小。對於buffer,您可能正在尋找strlen()

一旦你解決以上,你需要確保results爲有效NUL結尾的字符串結束。這對於printf()正常工作是必需的。

+2

...或者'NULL'如果分配失敗。 – unwind 2012-01-30 15:08:07

+0

詳細說明,'sizeof(results)'和'sizeof(buffer)'返回在編譯時實際已知的指針的大小。標準C無法查詢動態分配的內存塊的大小。因此你必須記住你分配了多少。 – 2012-01-30 15:22:46

+0

你可以告訴我,我必須做些什麼來改變它,我的代碼工作正常嗎? – user1089679 2012-01-30 17:05:41

2

你的代碼只是盲目地向前邁進,看起來是根據「編譯,它必須工作」的範式編寫的。如果這聽起來很刺耳,我很抱歉,當然這不是對你個人的評論。

你需要真的看看在API的文檔:你正在嘗試使用,並分析你的使用是否有意義。

您不能忽略realloc()的返回值,您將如何獲取新分配的內存?它不能改變你現有的指針,因爲你通過價值傳遞它。

動態數組一般需要工作的方式是保持的三件事情軌跡:

  • 當前數組的基址
  • 元素(字節,你的情況),該數組保存的數現在
  • 元件的所述陣列可容納,最大值(前它需要增長)

追加當數ñ新的元素,你檢查是否這樣會溢出元素的數量,所以它變得大於最大值。這是不允許的,因此在這種情況下,您需要重新分配基本數組,以便新數據適合,並且(當然)相應地更新數組的狀態。

1

realloc(results,sizeof(results)+ sizeof(buffer));

此行可能是問題。

  1. realloc()返回指定的大小分配的新地址,而且也沒有保證,這將是相同的地址指針有過;所以,你應該總是重新指定你的指針:

    ptr = realloc(ptr,newSize);

  2. sizeof()不會返回指針的動態分配大小。在這種情況下,sizeof(results)sizeof(buffer)很可能總是返回8.您可能會替換爲:

    results = realloc(results,ctr * 514);
    其中ctr是在while之前用0初始化並計數迭代次數的short

  3. 由於緩衝器總是514你爲什麼不通過它redifining來降低負載:

    字符緩衝區[514];

    問候

+0

0指針是完全有效的,標準要求編譯器在這些情況下分配NULL指針。 – 2012-01-30 16:06:06

+0

我站好了。謝謝 – whitelionV 2012-01-30 16:13:53