复制构造函数未调用(再次)
我不喜欢带有调试会话和粘贴内存指针的问题,但我被迫问这样的问题。 这是一个关于调用复制构造函数的问题。我知道已经有关于这个问题的答案,但我没有找到任何可以解决我的问题的东西
我有一个 Matrix 类:
class Matrix {
...
Matrix(const Matrix& other); // copy constructor, needed due to *data
private:
int *data;
};
Matrix 包含一个指向静态内存数组 data
的指针,所以当我复制一个矩阵,静态数组也应该用mempy
复制。
在某一时刻,我想将 Matrix 对象复制到另一个 Matrix。
debug("COPY BEGIN ");
debug("matricex before copy: " << &itsMatrix << " < " << &matrix);
itsMatrix = matrix;
debug("COPY END ");
debug("matricex after copy: " << &itsMatrix << " < " << &matrix);
应该调用复制构造函数来复制数据
。显然,不是调用构造函数,而是仅复制指针的值;稍后,当两个内存矩阵都被删除时,同一个指向数据
的指针被删除两次,并且出现段错误
这是一个调试会话:
1: Matrix.cpp MATRUX EMPTY 0xbf901a28 with empty data 0
2: include/SubArrayMax.hpp COPY BEGIN
3: include/SubArrayMax.hpp matricex before copy: 0xbf901a28 < 0xbf901a3c
--- here I should see a copy constructor ---
--- but no debug string is printed ---
4: include/SubArrayMax.hpp COPY END
5: include/SubArrayMax.hpp matricex after copy: 0xbf901a28 < 0xbf901a3c
6: Matrix.cpp DELETE MATRIX 0xbf901a28 with data 0x81d0550
7: Matrix.cpp DELETE MATRIX 0xbf901a3c with data 0x81d0550
--- 0x81d0550 is deleted twice ---
这是我的复制构造函数:
Matrix::Matrix(const Matrix& other) // copy construcutor
{
...
data = new mval_t[dim.w * dim.h];
memcpy(data, other.data, dim.w * dim.h * sizeof(mval_t));
debug("MATRIX " << this << " after copying, data " << data);
}
我知道编译器可以减少复制构造函数,我尝试了 -fno-elide-constructors
并且也遇到了 seg 错误。
有任何提示为什么会发生这种情况吗?或者也许有更好的方法来处理具有副作用的复制对象?
I don't like questions with debug sessions and memory pointers pasted, but I am forced to ask one like that.
This is a question about invoking copy constructors. I know there are already answers about that, but I didn't find anything that would solve my problem
I have a Matrix class:
class Matrix {
...
Matrix(const Matrix& other); // copy constructor, needed due to *data
private:
int *data;
};
Matrix contains a pointer to a static memory array data
, so when I copy a Matrix, the static array should be also copied with mempy
.
At one point, I want to copy Matrix object to another Matrix
debug("COPY BEGIN ");
debug("matricex before copy: " << &itsMatrix << " < " << &matrix);
itsMatrix = matrix;
debug("COPY END ");
debug("matricex after copy: " << &itsMatrix << " < " << &matrix);
The copy constructor should be invoked to copy the data
. Apparently, instead of invoking the constructor, only values of the pointers are copied; later when both memory matrices are deleted, the same pointer to data
is deleted twice and I have seg fault
Here is a debug session:
1: Matrix.cpp MATRUX EMPTY 0xbf901a28 with empty data 0
2: include/SubArrayMax.hpp COPY BEGIN
3: include/SubArrayMax.hpp matricex before copy: 0xbf901a28 < 0xbf901a3c
--- here I should see a copy constructor ---
--- but no debug string is printed ---
4: include/SubArrayMax.hpp COPY END
5: include/SubArrayMax.hpp matricex after copy: 0xbf901a28 < 0xbf901a3c
6: Matrix.cpp DELETE MATRIX 0xbf901a28 with data 0x81d0550
7: Matrix.cpp DELETE MATRIX 0xbf901a3c with data 0x81d0550
--- 0x81d0550 is deleted twice ---
and this is my copy constructor:
Matrix::Matrix(const Matrix& other) // copy construcutor
{
...
data = new mval_t[dim.w * dim.h];
memcpy(data, other.data, dim.w * dim.h * sizeof(mval_t));
debug("MATRIX " << this << " after copying, data " << data);
}
I know that copy constructors can be reduced by compiler, I tried -fno-elide-constructors
and I also had seg fault.
Any hint why this happens? or maybe there is a better way to deal with copying objects with side effects?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,在您的情况下,将调用赋值运算符。
只需定义
No, in your case the assignment operator will be called.
Just define
示例代码片段中的行不会导致调用复制构造函数。它将使用运算符=,这可能没有实现,因为您获得的行为与默认的浅拷贝匹配。
尝试使用与复制构造函数类似的逻辑来实现运算符=。不过,不要忘记检查自我分配。
The line in your sample snippet will not cause the copy constructor to be called. It will use operator = which probably wasn't implemented since the behavior you are getting matches the default shallow copy.
Try implementing operator = with similar logic to your copy constructor. Don't forget to check for self assignment though.