Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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++ 如何防止临时文件超出范围?_C++_Vector_Scope_Copy_Raii - Fatal编程技术网

C++ 如何防止临时文件超出范围?

C++ 如何防止临时文件超出范围?,c++,vector,scope,copy,raii,C++,Vector,Scope,Copy,Raii,在以下情况下,我的对象超出范围,访问了无效指针: struct Animal { char* buffer; Animal() { buffer = new char[100]; } ~Animal() { delete[]buffer; } }; int main() { vector<Animal> list; { Animal dog; list.push_back(dog); }

在以下情况下,我的对象超出范围,访问了无效指针:

struct Animal
{
    char* buffer;
    Animal() { buffer = new char[100]; }
    ~Animal() { delete[]buffer; }
};


int main()
{
    vector<Animal> list;

    {
        Animal dog;
        list.push_back(dog);
    }

    list[0].buffer[50] = 7;  // Buffer's been deleted, can't access it
 }
但这仍然会创建一个临时的,除非对它进行优化,我不希望依赖它,因为在另一个地方(另一个编译器),它可能不会做同样的事情

编辑:多亏了Remy Lebeau,我了解到您可以直接在向量中构造向量元素,无需临时设置,无需复制,功能如下:

template< class... Args >
void emplace_back( Args&&... args );
模板
空侵位返回(Args&…Args);
我不知道可变模板参数是如何工作的,但描述如下:

将新元素追加到容器的末尾。元素是 通过std::allocator\u traits::construct构造,通常 使用“新放置”在该位置在位构造图元 由集装箱提供。参数args。。。已转发至 构造函数作为std::forward(args)


问题不在于临时措施超出了范围。真正的问题是,
Animal
没有实现复制构造函数或复制赋值操作符,从而违反了

当您将临时对象推入向量时,会生成对象的副本,但编译器生成的副本构造函数只是按原样复制指针,而不会分配内存的副本。因此,当临时文件被销毁时,内存将在析构函数中解除分配,副本将保留一个指向无效内存的悬空指针

添加复制构造函数以分配新内存:

struct Animal
{
    char* buffer;

    Animal() {
        buffer = new char[100];
    }

    Animal(const Animal &src) {
        buffer = new char[100];
        std::copy(src.buffer, src.buffer+100, buffer);
    }

    ~Animal() {
        delete[] buffer;
    }

    Animal& operator=(const Animal &rhs) {
        if (this != &rhs) {
            std::copy(rhs.buffer, rhs.buffer+100, buffer);
        }
        return *this;
    }
};
或者,使用
std::vector
代替原始指针,让编译器为您生成合适的复制构造函数、复制赋值运算符和析构函数:

struct Animal
{
    std::vector<char> buffer;
    Animal() : buffer(100) {}
};

问题不在于临时措施超出了范围。真正的问题是,
Animal
没有实现复制构造函数或复制赋值操作符,从而违反了

当您将临时对象推入向量时,会生成对象的副本,但编译器生成的副本构造函数只是按原样复制指针,而不会分配内存的副本。因此,当临时文件被销毁时,内存将在析构函数中解除分配,副本将保留一个指向无效内存的悬空指针

添加复制构造函数以分配新内存:

struct Animal
{
    char* buffer;

    Animal() {
        buffer = new char[100];
    }

    Animal(const Animal &src) {
        buffer = new char[100];
        std::copy(src.buffer, src.buffer+100, buffer);
    }

    ~Animal() {
        delete[] buffer;
    }

    Animal& operator=(const Animal &rhs) {
        if (this != &rhs) {
            std::copy(rhs.buffer, rhs.buffer+100, buffer);
        }
        return *this;
    }
};
或者,使用
std::vector
代替原始指针,让编译器为您生成合适的复制构造函数、复制赋值运算符和析构函数:

struct Animal
{
    std::vector<char> buffer;
    Animal() : buffer(100) {}
};

我不明白这个问题。你是在要求你把那些不是默认可构造的东西放入
std::vector
?这不是
reserve()
所做的。“然后我使用我的vectorofamals[0]并访问一个无效指针”你说的“无效指针”是什么意思?它在哪里?对不起,我最好重写一下question@TitoneMaurice您希望通过使用vector来防止这些问题,但在我看来,只关注vector是错误的。向量刚刚暴露了你的类的问题。解决复制问题(很容易通过使用<代码> STD::vector < /COD>或),或者使复制操作不被私有化和未实现,或使用C++ 11的<代码>删除> /代码>语法使类不可复制。我不理解这个问题。你是在要求你把那些不是默认可构造的东西放入
std::vector
?这不是
reserve()
所做的。“然后我使用我的vectorofamals[0]并访问一个无效指针”你说的“无效指针”是什么意思?它在哪里?对不起,我最好重写一下question@TitoneMaurice您希望通过使用vector来防止这些问题,但在我看来,只关注vector是错误的。向量刚刚暴露了你的类的问题。要么修复复制问题(很容易通过使用<代码> STD::vector < /COD>或),或者通过复制操作私自和未实现,或者使用C++的代码> >删除> /代码>语法,使类不可复制,谢谢。这是我不清楚的过错。我想学习如何避免复制。我认为有很多方法可以在向量中构造一个对象。@TitoneMaurice你的问题中没有任何东西暗示你的目标是避免复制。在C++11之前,您无法避免复制。在C++11及更高版本中,您可以使用
emplace\u back()
而不是
push\u back()
。但是,当一个类管理不能浅层复制的资源时,仍然应该遵循三的规则(以及C++11及更高版本中的五的规则)。vector::emplace_back()不起作用。当我执行myVector.emplace_back(myStruct(arg1,arg2));它首先构造myStruct,然后copy在向量中构造一个新的。一次只做一件事。如果emplace_back()不起作用,我想我应该问一个问题。@TitoneMaurice删除显式临时变量,只需自己传递构造函数参数:
myVector.emplace_back(arg1,arg2)
emplace\u back()
将在原地构造新对象时将参数转发给类型构造函数。谢谢。这是我不清楚的过错。我想学习如何避免复制。我认为有很多方法可以在向量中构造一个对象。@TitoneMaurice你的问题中没有任何东西暗示你的目标是避免复制。在C++11之前,您无法避免复制。在C++11及更高版本中,您可以使用
emplace\u back()
而不是
push\u back()
。但是,当一个类管理不能浅层复制的资源时,仍然应该遵循三的规则(以及C++11及更高版本中的五的规则)。vector::emplace_back()不起作用。当我执行myVector.emplace_back(myStruct(arg1,arg2));它首先构造myStruct,然后copy在向量中构造一个新的。一次只做一件事。如果emplace_back()不起作用,我想我应该问一个关于