【问题标题】:Crash from a push_back() in a std vector从 std 向量中的 push_back() 崩溃
【发布时间】:2013-10-26 01:23:09
【问题描述】:

这个程序按预期工作:

#include <iostream>
#include <string>
#include <vector>    
using namespace std;

struct Thumbnail
{
    string  tag;
    string  fileName;
};

int main()
{
    {
        Thumbnail newThumbnail;
        newThumbnail.tag = "Test_tag";
        newThumbnail.fileName = "Test_filename.jpg";

        std::vector<Thumbnail> thumbnails;

        for(int i = 0; i < 10; ++i) {
            thumbnails.push_back(newThumbnail);
        }
    }
    return 0;
}

如果我将主代码块复制并粘贴到另一个项目(仍然是单线程)中,在任何函数中,我都会从注释 // &lt;-- crash at the 2nd loop 的行中得到这个异常:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

如果我在任何 push_back 之前清除向量,一切都很好(但这当然不是所需的行为);这让我觉得这就像向量不能存储多个这样的对象。

这是代码崩溃的函数:

int ImageThumbnails::Load(const std::string &_path)
{
    QDir thumbDir(_path.c_str());

    if(!thumbDir.exists())
        return errMissingThumbPath;

    // Set a filter
    thumbDir.setFilter(QDir::Files);
    thumbDir.setNameFilters(QStringList() << "*.jpg" << "*.jpeg" << "*.png");
    thumbDir.setSorting(QDir::Name);

    // Delete previous thumbnails
    thumbnails.clear();

    Thumbnail newThumbnail;

    ///+TEST+++
    {
        Thumbnail newThumbnail;
        newThumbnail.tag = "Test_tag";
        newThumbnail.fileName = "Test_filename.jpg";

        std::vector<Thumbnail> thumbnails;

        for(int i = 0; i < 10; ++i)
        {
            TRACE << i << ": " << sizeof(newThumbnail) << "  /  " << newThumbnail.tag.size() << " / " << newThumbnail.fileName.size() << std::endl;
            //thumbnails.clear();                   // Ok with this decommented
            thumbnails.push_back(newThumbnail);     // <-- crash at the 2nd loop
        }

        exit(0);
    }
    ///+TEST+END+++
...

这是输出:

> TRACE: ImageThumbnails.cpp:134:Load  
0: 8  /  8 / 17
> TRACE: ImageThumbnails.cpp:134:Load  
1: 8  /  8 / 17
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

为什么在两个不同的项目中,同一段代码会出现这种不同的行为?

平台:Windows 7、MinGW 4.4、GCC

【问题讨论】:

  • 您确定您的程序没有崩溃,而其他程序正在发生其他事情吗?例如在另一个线程中?
  • 这道题和测试用例都不行!
  • 你在其他项目中对Thumbnail有同样的定义吗?
  • @itwasntpete:是的,我是。它是一个单线程应用程序。
  • 另一个程序中的某个地方很可能存在内存损坏,当您在其中添加 std::vector 时,这会表现出来。

标签: c++ vector crash push-back


【解决方案1】:

补充一下(因为第一个 Google 结果):在我的情况下,我得到了bad_alloc,即使我还有几 GB 的 RAM 可用。

如果您的应用程序需要超过 2GB 的内存,您必须在链接器设置中启用 /LARGEADDRESSAWARE 选项。

如果您需要超过 4GB,您必须将构建目标设置为 x64(在项目设置和构建配置中)

由于矢量自动调整大小的工作原理,您将在 ~1gb / ~2gb 矢量大小处遇到断点

【讨论】:

    【解决方案2】:

    如果在另一个应用程序中使用完全相同的代码时崩溃,则程序可能内存不足(std::bad_alloc 异常可能是因为这个原因)。检查您的其他应用程序正在使用多少内存。

    另一件事......在使用 std::vectors 时使用 reserve() 方法,您可以提前知道有多少元素将被推入向量中。看起来您正在推动完全相同的元素 10 次。为什么不使用包含默认对象参数的 resize() 方法?

    【讨论】:

    • 我推送同一个元素只是为了测试。
    • 使用 reserve() 它不再崩溃。这更奇怪了!
    • 会不会是reserve()和push_back()使用不同的方法向系统申请内存,只有第一个成功?
    • 如果推送的元素多于保留的元素会怎样?假设您保留 100 个元素,然后推送 101 个元素。然后会发生什么?
    • 因此,不包括性能,从观察者的角度来看,只是 push_back 一个元素或为其保留空间然后将其推回应该没有区别。
    猜你喜欢
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    相关资源
    最近更新 更多