2013-05-31 181 views
0

我有一個返回一個指向結構如下功能:內存損壞

//header file 
typedef struct { 
     unsigned char *buffer; 
     uint8_t  len; 
} T_ABC_PACKET 
主文件

,我創建了一個指向函數的指針,並試圖把它打印出來

T_ABC_PACKET *pct = NULL; 
pct = function_that_return_the_packet; 
printf("value of packet is %s \n", pct->buffer); 

結果在打印功能中始終保持一致。我期望緩衝區有8個字節,最後一個字節總是損壞的內存。 值爲10000357`2U

但如果我打印功能內的緩衝液:

T_ABC_PACKET* function_that_return_the_packet { 

T_ABC_PACKET *pct = NULL; 
char string_temp[80]; 
//some more initialization... 
pct->buffer = (unsigned char *)string_temp; 
pct->len = 5; 
printf("value of packet is %s \n", pct->buffer); 
return pct; 
} 

在功能打印的值是10000357f。只有最後一個字符被損壞。 這總是提供一致的值,沒有多少次運行程序,只有最後一個字符在函數的調用者中被破壞。 我知道一個可能的情況是內存泄漏,但我試圖仔細檢查,我找不到任何泄漏。如何獲得pct->緩衝區以正確使用所有內容?

+0

你是否正在爲函數內的「pct」分配內存。 – Jay

+0

只是提一個問題的提示:你通常應該提供一個[簡短的,獨立的,可編輯的例子](http:// sscce。org /),這樣人們可以最好地理解你的問題。否則,我們無法確定您發佈的代碼段實際上是否包含問題。 –

+0

您已刪除導致問題的確切行。無論「更多初始化」是什麼,它都在做非常非法的事情。請下次顯示所有相關代碼,包括錯誤的位。 –

回答

5

看起來您正在返回一個指向未定義行爲的局部變量的指針,string_temp位於function_that_return_the_packet的本地並且在您退出該函數後將不存在。

pct->buffer = strdup(string_temp); 

只要確保你檢查它並沒有失敗:

丹尼爾·使用strdup可能是解決問題的最簡單的方法建議。您當然也可以使用malloc,然後使用strcpy

+0

@Shafik Yaghmour:如果它是未定義的行爲,爲什麼只有最後一個字符被損壞?以及我應該如何解決上述錯誤,以便我可以正確地獲取數據包的值? – xambo

+1

@xambo「未定義的行爲」意思就是:行爲未定義。所以沒有(對程序員來說)字節被破壞的原因。也許如果你明天運行它,所有的字節將會是。它*未定義*。 –

+0

@xambo這是未定義的行爲,所以你可以對結果沒有任何期望。我還更新瞭解決方案,可能還有其他問題,如果沒有SSCCE,很難知道。 –

1

一旦你解決返回一個指針到本地的未定義行爲(見沙菲克Yaghmour回答)你仍然有不確定的操作:看來緩衝區不是空ternminated,所以%s格式說明讀取過去吧,只有停止當它發現一個不相關的\0

如果你知道緩衝區的長度不得超過8個,你可以在結束了複製其內容pct->len成字符緩衝區,theninsert終止:

char tmpBuf[9]; // max length is 8, plus one for null ternminator 
memcpy(tmpBuf, pct->buffer, pct->len); 
tmpBuf[pct->len] = '\0'; 
printf("value of packet is %s \n", tmpBuf); 
0

這是問題的根源:

pct->buffer = (unsigned char *)string_temp; 

'string_temp'被分配在堆棧上。當函數返回時,它會在後面的某處被銷燬,或者不是,就像你的情況一樣,除了最後一個字節。

您應該:

使用strdup(),而不是在該行分配。

當您完成整個結構時,請在釋放整個結構之前使用free()釋放該字符串。