std::vector 保留方法无法分配足够的内存

发布于 2024-08-15 19:47:27 字数 1434 浏览 8 评论 0原文

我的 C++ 应用程序中有一个缓冲区类,如下所示:

class Buffer
{
    public:
    Buffer(size_t res): _rpos(0), _wpos(0)
    {
        _storage.reserve(res);
    }

    protected:
    size_t _rpos, _wpos;
    std::vector<uint8> _storage;
}

有时使用构造函数会失败,因为它无法分配所需的内存空间。例如,有一次,使用 res = 37 调用构造函数导致了段错误,并从其核心转储中获得了以下堆栈跟踪:

#0  0x00007f916a176ed5 in raise () from /lib/libc.so.6
No symbol table info available.
#1  0x00007f916a1783f3 in abort () from /lib/libc.so.6
No symbol table info available.
#2  0x00007f916a1b33a8 in ?? () from /lib/libc.so.6
No symbol table info available.
#3  0x00007f916a1b8948 in ?? () from /lib/libc.so.6
No symbol table info available.
#4  0x00007f916a1bb17c in ?? () from /lib/libc.so.6
No symbol table info available.
#5  0x00007f916a1bca78 in malloc () from /lib/libc.so.6
No symbol table info available.
#6  0x00007f916ac0c16d in operator new (sz=37)
    at ../../.././libstdc++-v3/libsupc++/new_op.cc:52
        p = <value optimized out>
#7  0x00000000004e3d11 in std::vector<unsigned char, std::allocator<unsigned char> >::reserve (this=0x7f911bc49cc0, __n=31077)
    at /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.4.2/../../../../include/c++/4.4.2/ext/new_allocator.h:89
        __old_size = 0
        __tmp = <value optimized out>

我使用 GCC 4.4.2 作为 64 位编译了此应用程序应用程序,我在 Debian 5 x64 中使用它。

非常感谢任何帮助。 谢谢

I have a buffer class in my C++ application as follows:

class Buffer
{
    public:
    Buffer(size_t res): _rpos(0), _wpos(0)
    {
        _storage.reserve(res);
    }

    protected:
    size_t _rpos, _wpos;
    std::vector<uint8> _storage;
}

Sometimes using the constructor fails because its unable to allocate the required memory space. For example, once, calling the constructor with res = 37 caused a segfault with the following stack trace that i got from its core dump:

#0  0x00007f916a176ed5 in raise () from /lib/libc.so.6
No symbol table info available.
#1  0x00007f916a1783f3 in abort () from /lib/libc.so.6
No symbol table info available.
#2  0x00007f916a1b33a8 in ?? () from /lib/libc.so.6
No symbol table info available.
#3  0x00007f916a1b8948 in ?? () from /lib/libc.so.6
No symbol table info available.
#4  0x00007f916a1bb17c in ?? () from /lib/libc.so.6
No symbol table info available.
#5  0x00007f916a1bca78 in malloc () from /lib/libc.so.6
No symbol table info available.
#6  0x00007f916ac0c16d in operator new (sz=37)
    at ../../.././libstdc++-v3/libsupc++/new_op.cc:52
        p = <value optimized out>
#7  0x00000000004e3d11 in std::vector<unsigned char, std::allocator<unsigned char> >::reserve (this=0x7f911bc49cc0, __n=31077)
    at /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.4.2/../../../../include/c++/4.4.2/ext/new_allocator.h:89
        __old_size = 0
        __tmp = <value optimized out>

I've compiled this application using GCC 4.4.2 as a 64 bit application and I'm using it in Debian 5 x64.

Any help is much appreciated.
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我不是你的备胎 2024-08-22 19:47:27

因为段错误发生在 malloc 中,所以很可能其他一些代码已经破坏了堆(即写入它们不拥有但正在由堆管理器使用的内存部分)。

我建议使用 Valgrind 来查找哪些代码正在破坏堆。

Because the segfault is in malloc, most likely some other code has trashed the heap (i.e. written to parts of memory they do not own and are being used by the heap manager).

I recommend using Valgrind to find what code is trashing the heap.

野稚 2024-08-22 19:47:27

如果您无法使用 Valgrind 找出内存损坏的位置,因为它意味着重负载,您仍然可以使用较轻的解决方案进行测试。

对于 Valgrind 不适用的服务器应用程序(因为该平台位于 Solaris 8 上),我使用 mpatrol ( http: //mpatrol.sf.net ),尤其是 dmalloc ( http://dmalloc.com )。

在某种程度上,您可以使用它们而无需重新编译(只需重新链接 dmalloc、预加载 mpatrol 库)。它们将替换内存原语,以对内存使用情况执行额外的检查(这些原语的错误参数、逐一读取、堆损坏等)其中一些检查将在问题发生时准确触发,而另一些检查将被触发会比实际的错误代码晚一点被触发。通过调整启用哪些检查以及适用时的检查频率,您可以在执行基本检查时几乎全速运行。

我建议使用 dmalloc 重新编译以获得所谓的“FUNC_CHECK”,对我来说,这增加了错误发现的准确性,而性能成本可以忽略不计。

If you can't use Valgrind to find out where your memory is corrupted because of the heavy load it implies, you can still test with lighter solutions.

For server application where Valgrind was not applicable (because the platform was on Solaris 8), I had pretty good result with mpatrol ( http://mpatrol.sf.net ) but especially dmalloc ( http://dmalloc.com ).

To some extend, you can use them without recompiling (just relinking for dmalloc, library preloading for mpatrol). They'll replace the memory primitives to perform extra checks on the memory use (bad argument to those primitives, reading off-by-one, heap corruption, ...) Some of those checks will be triggered exactly when the problem occurs while others will be triggered a bit later than the actual bad code. By tuning which checks are enabled, and when applicable the check frequency, you can run at almost full speed while performing basic checks.

I recommend recompiling with dmalloc to get so called 'FUNC_CHECK', for me, this added a lot of accuracy in bug spotting with a negligible performance cost.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文