2013-02-13 69 views
0

我遇到了一個奇怪的問題,對我沒有任何意義。保持對象存活的問題

我有一個結構(包含字符串)上限定爲API如下:

typedef struct sNCharcb 
{ 
    char * pData; 
    int iDataLen; 
} 
tsNCharcb; 

我需要保存這個結構的深層副本。我已經創建了一個實用的功能,使這個結構的副本:

inline sNCharcb rapi_strcpy(const sNCharcb &rapistr) 
{ 
    sNCharcb res; 

    res.pData = new char[rapistr.iDataLen]; 
    strcpy(res.pData, rapistr.pData); 
    res.iDataLen = rapistr.iDataLen; 

    return res; 
} 

我創建一個使用這個工具方法這些「sNCharcb」結構的副本,並將它們保存到引用父對象變量:

stored_sNCharcb = rapi_strcpy(sNCharcb_to_copy); 

經過一段時間後,這些存儲值被神奇地更改爲包含一些隨機垃圾。存儲這些值的父對象始終處於作用域內,並且不會被破壞。什麼可能導致這些值過早被抹去?

+0

是否有一個理由,爲什麼你不'的std :: string'呢? – 2013-02-13 20:40:07

+0

您應該爲此類實現有意義的拷貝構造函數,賦值運算符和析構函數。或者將問題標記爲C.或者只是使用'std :: string'數據成員而不是'char *',所有問題都會消失。 – juanchopanza 2013-02-13 20:43:26

+0

這是我無法更改的API。無論我喜不喜歡,我都必須玩C字符串。 – 2013-02-14 05:54:54

回答

1

是否在pData NULL中的數據終止?如果不是,則調用rapi_strcpy可能會運行結束,因此將複製超出目標中分配的大小。

你可能想使用一些強制的長度,像strncpymemcpy

strncpy(res->pData, rapistr.pData, rapistr.iDataLen); 
+0

數據應該是NULL終止的,但是我會按照建議更改方法。這樣更安全。 – 2013-02-14 05:58:28

+0

數據實際上不是NULL終止,並且rapi_strcpy按照您的建議運行並寫入它不應該觸及的部分內存。這導致了問題,並改變strcpy方法來強制長度固定的問題! – 2013-02-14 06:15:47

1

經過一段時間後,這些存儲值被神奇地改變爲包含一些隨機垃圾。

假設stored_sNCharcb時有效rapi_strcpy()退出,然後stored_sNCharcb在稍後的時間變化,那就表明你還沒有表現出被覆蓋stored_sNCharcb當它不應該,比如由於緩衝區溢出或代碼這樣。我建議你在rapi_strcpy()退出後在stored_sNCharcb上放置一個數據斷點,然後讓調試器告訴你它是否被修改,這樣你就可以準確地看到哪個代碼正在修改它。

+0

這被證明是診斷問題的好方法。確實是緩衝區溢出。 – 2013-02-14 06:16:57