Vector::push_back() 给出读取访问冲突
Posted
技术标签:
【中文标题】Vector::push_back() 给出读取访问冲突【英文标题】:Vector::push_back() gives read access violation 【发布时间】:2018-05-05 13:09:24 【问题描述】:我的类有一个问题,似乎只有在我尝试将我的一个对象添加到向量时才会出现。
分配工作正常除非在尝试插入向量时发生(这会在释放内存时导致以下错误:抛出异常:读取访问冲突this->elements
是0xCEDECEDF
)。
这是我的赋值运算符和我的复制构造函数。注意elements
是一个int**
指针。
Matrice& Matrice::operator=(const Matrice& other)
if (elements)
for (size_t i = 0; i < numberoflines; ++i)
if (elements[i])
delete[] elements[i];
delete[] elements;
id = other.id;
numberofcols= other.numberofcols;
numberoflines= other.numberoflines;
elements = new int*[numberoflines];
for (size_t i = 0; i < numberoflines; ++i)
elements[i] = new int[numberofcols];
for (size_t i = 0; i < numberoflines; ++i)
for (size_t j = 0; j < numberofcols; ++j)
elements[i][j] = other.elements[i][j];
return *this;
Matrice::Matrice(const Matrice& other)
*this = other;
这是Matrice
(Matrix) 类的标题:
#pragma once
#include<iostream>
class Matrice
public:
friend std::istream& operator>>(std::istream&, Matrice&);
friend std::ostream& operator<<(std::ostream&, const Matrice&);
Matrice(const unsigned, const unsigned, const unsigned);
Matrice();
Matrice(const Matrice&);
~Matrice();
Matrice& operator=(const Matrice&);
int operator~()const;
bool operator<(const Matrice&)const;
private:
unsigned id;
unsigned numberoflines;
unsigned numberofcols;
int** elements;
;
下面是构造函数和析构函数:
Matrice::Matrice(unsigned id, unsigned numberoflines, unsigned numberofcols)
this->id = id;
this->numberoflines = numberoflines;
this->numberofcols = numberofcols;
elements = new int*[numberoflines];
for (size_t i = 0; i < numberoflines; ++i)
elements[i] = new int[numberofcols];
Matrice::Matrice()
numberofcols = 1;
numberoflines = 1;
elements = new int*[numberoflines];
for (size_t i = 0; i < numberoflines; ++i)
elements[i] = new int[numberofcols];
Matrice::~Matrice()
if (elements)
for (size_t i = 0; i < numberoflines; ++i)
if (elements[i])
delete[] elements[i];
delete[] elements;
最后我只是在 main 中执行此操作:
std::vector<Matrice> vec;
Matrice obj;
vec.push_back(obj);
【问题讨论】:
Matrice
类是什么样的?
所有构造函数都初始化elements
成员吗?在现代 C++ 中,很少有任何好的理由使用 new
或 delete
关键字 - 只需使用 vector
或智能指针即可避免大多数此类问题。
我知道这不是最好的方法,但我受到学校的限制,无法使用 new
和 delete
它也对我有用。非常感谢。我是这个项目的瓶颈,我讨厌它。但是你有理由解释为什么这可以解决问题吗?
您可能希望在赋值运算符的顶部执行if (this == &other) return *this;
,以防止自赋值。
【参考方案1】:
您的复制构造函数调用赋值运算符。赋值运算符以以下代码开头:
if (elements)
for (size_t i = 0; i < numberoflines; ++i)
if (elements[i])
delete[] elements[i];
delete[] elements;
这会导致拷贝构造函数出现问题,因为拷贝构造函数中没有任何东西初始化elements
,所以它会指向内存中的一个随机位置。在你的情况下,那是0xCEDECEDF
。因此elements
是非零的,它在 C++ 中总是计算为true
,所以我上面引用的代码将尝试删除实际上没有分配的内存。
将行 elements = nullptr;
添加到复制构造函数后,elements
的值现在被解释为 false
,因此会跳过 if
块,并且不会调用释放代码。
另一种实现in C++11 的方法(恕我直言更明智)是在类声明本身中初始化nullptr
:
unsigned numberofcols;
int** elements = nullptr; // CHANGE HERE
;
这样,编译器将在每次创建新对象时初始化elements
,您不必担心忘记在您的构造函数中这样做。
顺便说一句,您的复制构造函数有一个疏忽;您应该首先确保this
和other
不是同一个对象。
【讨论】:
以上是关于Vector::push_back() 给出读取访问冲突的主要内容,如果未能解决你的问题,请参考以下文章
没有匹配函数调用‘std::vector::push_back(std::string&)’
vector::push_back 和 string::push_back 之间的区别?
在展开期间将向量成员推入向量:vector.push_back(vector[0])