c++ - vector 指针<unique ptr> 上的 Sysmalloc 错误第二次推回

标签 c++ vector unique-ptr

对于学校作业,我需要跟踪 Product 类的多个实例。

在我的程序的主要部分,我正在制作一个 vector ,如下所示:

std::vector<std::unique_ptr<Product>> products;

在我的 main 中的特定条件下,我将此 vector 作为指向另一个名为 processData 的函数的指针传递。这个看起来像这样(尽可能简化):
void processData(std::vector<std::unique_ptr<Product>>* products)
{
while (true)
{
    //Do something with std::cin
    //Do something with that data
    products->push_back(std::unique_ptr<Product>(new Product(dataX, dataB)));
}
}

会发生什么

第一次反击很顺利。它正在做它应该做的事情。但是,第二次调用 push_back 会导致以下错误:
main: malloc.c:2385: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.

我对此的看法

我认为在执行第一个 push_back 命令后,指向 vector 的指针正在更改。因为设备必须重新分配内存。因此,当想要执行第二个 push_back 时,指针指向一个无效的位置。

我试图做些什么来解决这个问题

我尝试使用 emplace_back 函数,但我已经知道这行不通。

在我的程序主体中,我目前正在执行以下代码,然后调用 processData 函数:
products.reserve(100);

为什么?

因为我认为这会为 100 个 Product 指针分配足够的空间,所以它不会重新分配内存。

目前我仍然遇到上述问题。
我希望你们能指出我正确的方向。

使用前代码

您将需要输入一些数据。数据如下所示:
#Data|<six numbers>|<two numbers>%

例子:
#Data|123456|12%

放入多个后,它会崩溃。removePrefix 似乎是原因,不确定。
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <memory>

#define END_MSG                 "End"
#define PRODUCT_NUMBER_LENGTH   6
#define AMOUNT_OF_SEPERATORS    2
#define STRING_BEGIN_INDEX      0

struct Product{
    int productNumber;
    int quantity;
    Product(int productNumber, int quantity) : productNumber(productNumber), quantity(quantity)
    {   
    }
};


void removePrefix(std::string* msg)
{
    if (msg != nullptr)
    {
        msg->erase(msg->begin());
        msg->erase(msg->end());
    }
}

void processData(std::vector<std::unique_ptr<Product>>& products)
{
    std::string DATA_MSG = "Data";
    std::string data;

    bool process = true;
    while (process)
    {
        std::cin >> data;
        removePrefix(&data);
        if (data.compare(END_MSG) != 0)
        {
            if (data.find(DATA_MSG) != std::string::npos &&
                    std::count(data.begin(), data.end(), '|') == AMOUNT_OF_SEPERATORS)
            {
                data.erase(STRING_BEGIN_INDEX, DATA_MSG.length() + 1); //including the first "|"
                int productNumber = std::stoi(data.substr(STRING_BEGIN_INDEX, PRODUCT_NUMBER_LENGTH));
                int quantity = std::stoi(data.substr(PRODUCT_NUMBER_LENGTH + 1));

                products.push_back(std::unique_ptr<Product>(new Product(productNumber, quantity)));
            }
        }
        else
        {
            process = false;
        }
    }
}


int main()
{
    std::string input;
    std::vector<std::unique_ptr<Product>> products;
    products.reserve(100);

    while (true)
    {
        processData(products);
    }
    return 0;
}

最佳答案

It seems like removePrefix is the causer, not sure.

void removePrefix(std::string* msg)
{
    if (msg != nullptr)
    {
        msg->erase(msg->begin());
        msg->erase(msg->end());
    }
}

msg->end()是字符串中最后一个字符之后的迭代器。它不是指可以从字符串中删除的字符。进一步检查 nullptr但您不检查字符串的大小。如果字符串为空,则 begin() == end()并且两个调用都将尝试删除不存在的东西。

传递 nullptr 时请不要到处传递指针没有意义。如果您没有字符串,则不会调用该函数,因此您永远不需要使用 nullptr 调用它。 .改用引用:
 void removePrefix(std::string& msg)
 {
     if (msg.size() >= 2) {
         msg.erase(msg.begin());
         msg.erase(msg.end() - 1);
     }
 }

PS:您还有另一个要删除的电话:
data.erase(STRING_BEGIN_INDEX, DATA_MSG.length() + 1); 

同样在这里,我看不到您确保索引在范围内。但是,这将抛出 std::out_of_range异常(exception),这不是迭代器重载的情况(见 here )。

关于c++ - vector 指针<unique ptr> 上的 Sysmalloc 错误第二次推回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61791906/

相关文章:

c++ - 帮助连接大纲

c++ - 使用另一个指针在 `delete` 拥有的对象上调用 `unique_ptr`

c++ - 序列化一个浮点 vector

c++ - 找不到体系结构 x86_64 的符号(带有 xcode 的 OpenGL)

c++ - 为什么 clang 不警告模板中的死代码?

c++ - 如何检查2D vector 元素是否在某个索引范围内

c++ - 将此代码更改为追加而不是覆盖 (.Wav)

c++ - vector 预分配无法正常工作

c++ - 涉及 const unique_ptr 的 move 构造函数

c++ - make_unique完美转发