【发布时间】:2020-09-17 04:10:55
【问题描述】:
我正在创建伪 std::vector。我希望能够声明变量Matrix B,然后为其赋值,然后由另一个Matrix 变量传递。
Matrix 有构造函数,分配备忘录
Vect(int size, char name) : name(name), size(size), store(new int[size]){}
以及在 var 生命周期结束时将其删除的析构函数
~Vect(){
std::cout << "memo located: " << name << std::endl;
delete[] store;
}
不幸的是,用于返回值的方法返回它并调用了析构函数
Vect operator- (){
Vect b(size,'C');
for (int i = 0; i < size; i++){
b.store[i] = -store[i];
}
return b; // <- here it calls destructor!!!
}
我尝试这样做:
Vect m2;
Vect m1 = Vect(10, 'A');
m2 = -m1;
我得到这个错误:
memo located: C
-1, -2, -3, -4, -5, -6, -7, -8, -9, -10,
memo located: A
memo located: C
a.out(46158,0x109e71dc0) malloc: *** error for object 0x7f9162401850: pointer being freed was not allocated
a.out(46158,0x109e71dc0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6
如何在保存功能的情况下四处走动? 我的代码:
#include <iostream>
class Vect {
int *store;
int size = 0;
char name;
public:
Vect operator- (){
Vect b(size,'C');
for (int i = 0; i < size; i++){
b.store[i] = -store[i];
}
return b;
}
int *getPointer(){
return store;
}
int getSize(){
return size;
}
bool set(int i, int v){
if (i >= size)
return false;
store[i] = v;
return true;
}
Vect(){}
Vect(int size, char name) : name(name), size(size), store(new int[size]){}
~Vect(){
std::cout << "memo located: " << name << std::endl;
delete[] store;
}
};
int main(int argc, char **argv){
Vect m2;
Vect m1 = Vect(10, 'A');
int i = 0;
while(m1.set(i++, i));
m2 = -m1;
int size = m2.getSize(), *ptr = m2.getPointer();
for (int i = 0; i < size; i++){
std::cout << ptr[i] << ", ";
}
std::cout << std::endl;
return 0;
}
【问题讨论】:
-
另外
while(m1.set(i++, i));可能会导致undefined behavior。 在没有任何中间序列点(C++11 之前)的表达式中对同一标量进行多次修改,这些点是未排序的(C++11 起). -
1, 2:不,它没有回答我的问题q 3:我知道,我不是在问...
-
(1, 2) 是的,它确实
m2 = -m1;调用了复制原始指针store并留下m1和m2的内置赋值运算符,两者都认为他们拥有内存导致双重删除。Vect m1 = Vect(10, 'A');也调用了复制构造函数——同样的问题只是在这里m1现在持有一个指向已删除内存的指针。在内存缓冲区内部使用std::vector或std::unique_ptr -
@Krasnay Danil 是的,这正好回答了你的问题。你甚至读过他们的联系吗?了解 3 的规则(从 C++11 开始的 5 个),你就会知道哪里出了问题。
-
@Krasnay Danil 没有绕行。如果您编写一个默认复制/移动不够用的类,您基本上有三个选择:您要么实现所需的复制和移动操作,要么删除它们以防止它们被使用,或者您可以尝试更改您的班级因此可以使用默认班级。如果无法以这种方式实现您的类并且您想要复制/移动,那么根本无法实现 5 规则
标签: c++ oop constructor destructor