对于学校作业,我需要跟踪 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/