Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 向量指针上的Sysmalloc错误<;独特的ptr>;第二次推回_C++_Vector_Unique Ptr - Fatal编程技术网

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