C++ 向量指针上的Sysmalloc错误<;独特的ptr>;第二次推回
对于学校作业,我需要跟踪C++ 向量指针上的Sysmalloc错误<;独特的ptr>;第二次推回,c++,vector,unique-ptr,C++,Vector,Unique Ptr,对于学校作业,我需要跟踪产品类的多个实例 在我的主要程序中,我制作了一个向量,如下所示: std::vector<std::unique_ptr<Product>> products; 发生了什么 第一次推回进行得很顺利。它正在做它应该做的事情。但是,第二次调用push_会导致以下错误: main: malloc.c:2385: sysmalloc: Assertion `(old_top == initial_top (av) && old_size
产品
类的多个实例
在我的主要程序中,我制作了一个向量,如下所示:
std::vector<std::unique_ptr<Product>> products;
发生了什么
第一次推回进行得很顺利。它正在做它应该做的事情。但是,第二次调用push_会导致以下错误:
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
命令后,指向向量的指针正在更改。因为设备必须重新分配内存。因此,当想要执行第二个推回时,指针指向无效位置
我试图做什么来解决这个问题
我试着使用emplace\u back
功能,但我已经知道这不起作用
在调用processData
函数之前,我正在程序的main中执行以下代码:
products.reserve(100);
为什么?
因为我认为这会为100个Product
指针分配足够的空间,所以不会重新分配内存
目前,我仍然有上述问题。
我希望你们能给我指出正确的方向
在使用代码之前
您需要输入一些数据。数据如下所示:
#Data|<six numbers>|<two numbers>%
在放入多个后,它将崩溃。
似乎原因是removeffix
,不确定
#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;
}
void removePrefix(std::string* msg)
{
if (msg != nullptr)
{
msg->erase(msg->begin());
msg->erase(msg->end());
}
}
#包括
#包括
#包括
#包括
#包括
#定义结束消息“结束”
#定义产品编号长度6
#定义分隔符2的数量
#定义字符串\u开始\u索引0
结构产品{
int产品编号;
整数;
产品(整数产品编号,整数数量):产品编号(产品编号),数量(数量)
{
}
};
void removePrefix(std::string*msg)
{
如果(msg!=nullptr)
{
msg->erase(msg->begin());
msg->erase(msg->end());
}
}
void processData(标准::向量和乘积)
{
std::string DATA_MSG=“DATA”;
std::字符串数据;
布尔过程=真;
while(过程)
{
std::cin>>数据;
移除前缀(和数据);
如果(数据比较(结束消息)!=0)
{
if(data.find(data\u MSG)!=std::string::npos&&
std::count(data.begin()、data.end()、“|”)==分隔符的数量
{
data.erase(STRING_BEGIN_INDEX,data_MSG.length()+1);//包括第一个“|”
int productNumber=std::stoi(data.substr(字符串开始索引,产品编号长度));
int QUOTE=std::stoi(data.substr(产品编号+长度+1));
产品。推回(std::unique_ptr(新产品(产品编号、数量));
}
}
其他的
{
过程=假;
}
}
}
int main()
{
std::字符串输入;
std::向量积;
产品.储备(100);
while(true)
{
过程数据(产品);
}
返回0;
}
我认为您的问题在于unique\u ptr没有复制构造函数:
只要实例可以移动,push_back就可以工作。
对于emplace_back,直接创建实例。
--编辑:正如idclev463035818所指出的,这当然会导致complile错误,而不是运行时错误。
是的,push_-back有一个r-引用重载,我对此的陈述也相应地模糊,我已经对它进行了调整。我认为您的问题是unique_-ptr没有复制构造函数:
只要实例可以移动,push_back就可以工作。
对于emplace_back,直接创建实例。
--编辑:正如idclev463035818所指出的,这当然会导致complile错误,而不是运行时错误。
是的,push_-back有一个r-参考过载,我关于这个的陈述是模糊的,我已经调整了它
似乎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;
}
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
异常,迭代器重载的情况并非如此(请参阅)
似乎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;
}
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
异常,迭代器重载的情况并非如此(请参见)。请在问题中包含一个,在什么情况下,您会使用nullptr调用processData