2013-02-13 70 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