我正在尝试调试为Linux编写的遗留代码。有时,应用程序在通过以下方法到达memcpy调用时会出现段错误:
std::vector<uint8> _storage;
size_t _wpos;
void append(const uint8 *src, size_t cnt)
{
if (!cnt)
return;
if (_storage.size() < _wpos + cnt)
_storage.resize(_wpos + cnt);
memcpy(&_storage[_wpos], src, cnt);
_wpos += cnt;
}
值如下:
_storage.size() is 1000
_wpos is 0
*src points to an array of uint8 with 3 values: { 3, 110, 20 }
cnt is 3
我不知道为什么会发生这种情况,因为这个方法在应用程序运行时会被调用数千次,但有时会出现段错误。
任何人都知道如何解决这个问题?
答案 0 :(得分:4)
您的代码在写入的数据方面看起来很好。你绝对确定你传递了正确的src
指针吗?使用调试器(如gdb)运行代码时会发生什么?它应该停止在段错误上,然后您可以打印出_storage.size()
,src
和cnt
的值。
我相信你会发现(至少)其中一个根本不是你所期待的。您可能已通过无效src
;你可能已经过了一个荒谬的大cnt
。
答案 1 :(得分:2)
我建议在你的程序上运行valgrind。 发现早期的内存损坏是非常有价值的,因为它可能是你的程序的情况(因为它不是你得到的系统崩溃)。
答案 2 :(得分:1)
对于你给出的值,我不明白为什么会出现这种错误。由于早期的内存管理错误,您的段错误可能是延迟失败。在某些早期函数中写入向量的末尾可能会导致某些向量的内部成员被破坏,或者您可能意外地释放了之前向量使用的部分内存。我会检查操纵向量的其他函数,看看它们中是否有任何可疑的投射。
答案 3 :(得分:1)
我看到矢量的大小在增加。我从未看到它在减少。
接下来,vector
内置了内存管理支持。您可以将值插入到最后:
vector.insert( src, src+cnt );
这会将矢量扩展到正确的大小,并复制值。
答案 4 :(得分:0)
我唯一能想到的是_storage.resize()失败(应该抛出bad_alloc异常)。
另一种选择是通过调用push_back()来单独追加每个值(尽管可能要慢得多)。
答案 5 :(得分:0)
我在这里看到一个问题。 memcpy()函数从内存中复制n个字节,因此如果cnt是元素个数,则在调用memcpy时需要* sizeof(uint8)。
答案 6 :(得分:0)
在对我的另一个答案的评论中,你说“向量在另一个方法中得到清理,因为它是一个类成员变量。我将测试插入并看看会发生什么”。
线程安全怎么样?您是否绝对确定清除方法不会在调整大小时或在其后立即清除?由于这是一个“有时”问题,可能是由vector
中的内存管理并发访问引起的。