在 return 之后重写的数组内容
Content of array being rewritten after return
首先,我有下面的 class A
,同时有一个嵌套的 class B
:
// A.h
class A {
public:
class B;
A();
A(const A& a); // Copy constructor
B& operator[](const unsigned int& a) const;
A operator+(const A& a) const;
/*...*/
~A();
private:
/*...*/
unsigned int size;
B* b;
};
我正在尝试通过添加所述对象的两个 b
成员的内容,将重载的 +
运算符用于 "add" 两个 A
对象,并且将结果分配给第三个 A
对象。
b
是 B
个对象的动态分配数组。
B
是一个非常基本的 class,只有一些 unsigned int
这是主要功能:
// main.cpp
int main(int argc, char** argv) {
A a1, a2, result;
a1.read(argv[1]); // Initialize b member with content read from a file
a2.read(argv[2]); // Initialize b member with content read from a file
result = a1 + a2; // Error [3]
getchar();
return 0;
}
问题是,在尝试求和时,我得到了我认为是内存错误的内容,例如:HEAP[main.exe]: Invalid address specified to RtlValidateHeap( 00A50000, 00A59938 )
这里是 class A
的实现:
// A.cpp
A::A() : /*...*/, size(0), b(nullptr) {}
// Copy constructor
A::A(const A& a) : /*...*/, size(a.size), b(nullptr) {
b = new B[size]; // [1]
for (unsigned int i = 0; i < size; i++) {
(*this)[i] = a[i];
}
}
A::B& A::operator[](const unsigned int& i) const {
return b[i];
}
A A::operator+(const A& a) const {
if (size != a.size) {
exit(1); // Size must be the same on both operands
}
A tmp(*this); // Call to copy constructor
for (unsigned int i = 0; i < a.size; i++) {
tmp[i] += a[i];
}
return tmp; // Call to copy constructor [2]
}
A::~A() {
if (b != nullptr) {
delete[] b;
}
}
和 class B
:
// B.h
class A::B {
public:
B();
B(unsigned char, unsigned char, unsigned char);
B& operator+=(const B& b);
private:
unsigned int a, b, c, d;
};
// B.cpp
A::B::B() : a(0), b(0), c(0), d(0) {}
A::B::B(unsigned char _a, unsigned char _b, unsigned char _c) {
/*...*/
}
A::B& A::B::operator+=(const B& b) {
/*...*/
return *this;
}
顺便说一句,我正在使用 Visual Studio,在调试时我观察到:
b
成员 result
指向与 b
在 [1] 中相同的地址时[2] 中的 return 语句调用了复制构造函数,目前一切顺利
直到[2]中的returnb
的内容就可以了,比如:0x00669968 00 00 ff 00 00 ff 00 00 ..ÿ..ÿ..
在[3]之后b
的内容在[1]中因此内容result
对象的 b
成员变成类似:0x00669968 dd dd dd dd dd dd dd dd ÝÝÝÝÝÝÝÝ
,我猜是垃圾
注意:所有 include
指令和不相关的代码部分已被省略
两天来我一直在摇头试图找出问题所在,但运气不好,所以非常感谢您的帮助,在此先感谢。
我检查了您的代码,问题是您需要 class A
的自定义复制分配。在您的 main 中,您有 A a1, a2, result;
,为 3 个对象调用了默认构造函数。然后,在result = a1 + a2;
行中调用了默认的复制赋值。
When you have pointers in your class and allocate the memory using new then you have to worry about copy constructor and copy assignment. Check this post and the rule of three.
我建议你下一个代码:
class A {
class B {
unsigned a, b, c, d;
public:
B() : a(0), b(0), c(0), d(0) { }
B(unsigned char a_, unsigned char b_, unsigned char c_) : a(a_), b(b_), c(c_), d(0) { }
// Copy constructor.
B& operator=(const B& b_) {
a = b_.a;
b = b_.b;
c = b_.c;
d = b_.d;
return *this;
}
B& operator+=(const B& b_) {
a += b_.a;
b += b_.b;
c += b_.c;
d += b_.d;
return *this;
}
};
unsigned size;
B* b;
public:
A() : size(0) { }
// Copy constructor.
A(const A& a) : size(a.size) {
b = new B[size];
for (unsigned i = 0; i < size; ++i) {
b[i] = a[i];
}
}
// Copy assigment
A& operator=(const A& a) {
clear();
b = new B[size];
for (unsigned i = 0; i < size; ++i) {
b[i] = a[i];
}
return *this;
}
B& operator[](unsigned pos) const {
if (pos > size) {
throw std::out_of_range("Out of range");
}
return b[pos];
}
A operator+(const A& a) const {
A tmp = *this;
if (size != a.size) {
throw std::out_of_range("Diferent sizes");
}
for (unsigned i = 0; i < a.size; ++i) {
tmp[i] += a[i];
}
return tmp;
}
void read(const char* file) {
clear();
size = size_;
b = new B[size];
/*
* Read your file and update b.
*/
}
void clear() {
if (size) {
delete[] b;
size = 0;
}
}
~A() {
clear();
}
};
首先,我有下面的 class A
,同时有一个嵌套的 class B
:
// A.h
class A {
public:
class B;
A();
A(const A& a); // Copy constructor
B& operator[](const unsigned int& a) const;
A operator+(const A& a) const;
/*...*/
~A();
private:
/*...*/
unsigned int size;
B* b;
};
我正在尝试通过添加所述对象的两个 b
成员的内容,将重载的 +
运算符用于 "add" 两个 A
对象,并且将结果分配给第三个 A
对象。
b
是B
个对象的动态分配数组。B
是一个非常基本的 class,只有一些unsigned int
这是主要功能:
// main.cpp
int main(int argc, char** argv) {
A a1, a2, result;
a1.read(argv[1]); // Initialize b member with content read from a file
a2.read(argv[2]); // Initialize b member with content read from a file
result = a1 + a2; // Error [3]
getchar();
return 0;
}
问题是,在尝试求和时,我得到了我认为是内存错误的内容,例如:HEAP[main.exe]: Invalid address specified to RtlValidateHeap( 00A50000, 00A59938 )
这里是 class A
的实现:
// A.cpp
A::A() : /*...*/, size(0), b(nullptr) {}
// Copy constructor
A::A(const A& a) : /*...*/, size(a.size), b(nullptr) {
b = new B[size]; // [1]
for (unsigned int i = 0; i < size; i++) {
(*this)[i] = a[i];
}
}
A::B& A::operator[](const unsigned int& i) const {
return b[i];
}
A A::operator+(const A& a) const {
if (size != a.size) {
exit(1); // Size must be the same on both operands
}
A tmp(*this); // Call to copy constructor
for (unsigned int i = 0; i < a.size; i++) {
tmp[i] += a[i];
}
return tmp; // Call to copy constructor [2]
}
A::~A() {
if (b != nullptr) {
delete[] b;
}
}
和 class B
:
// B.h
class A::B {
public:
B();
B(unsigned char, unsigned char, unsigned char);
B& operator+=(const B& b);
private:
unsigned int a, b, c, d;
};
// B.cpp
A::B::B() : a(0), b(0), c(0), d(0) {}
A::B::B(unsigned char _a, unsigned char _b, unsigned char _c) {
/*...*/
}
A::B& A::B::operator+=(const B& b) {
/*...*/
return *this;
}
顺便说一句,我正在使用 Visual Studio,在调试时我观察到:
b
成员result
指向与b
在 [1] 中相同的地址时[2] 中的 return 语句调用了复制构造函数,目前一切顺利直到[2]中的return
b
的内容就可以了,比如:0x00669968 00 00 ff 00 00 ff 00 00 ..ÿ..ÿ..
在[3]之后
b
的内容在[1]中因此内容result
对象的b
成员变成类似:0x00669968 dd dd dd dd dd dd dd dd ÝÝÝÝÝÝÝÝ
,我猜是垃圾
注意:所有 include
指令和不相关的代码部分已被省略
两天来我一直在摇头试图找出问题所在,但运气不好,所以非常感谢您的帮助,在此先感谢。
我检查了您的代码,问题是您需要 class A
的自定义复制分配。在您的 main 中,您有 A a1, a2, result;
,为 3 个对象调用了默认构造函数。然后,在result = a1 + a2;
行中调用了默认的复制赋值。
When you have pointers in your class and allocate the memory using new then you have to worry about copy constructor and copy assignment. Check this post and the rule of three.
我建议你下一个代码:
class A {
class B {
unsigned a, b, c, d;
public:
B() : a(0), b(0), c(0), d(0) { }
B(unsigned char a_, unsigned char b_, unsigned char c_) : a(a_), b(b_), c(c_), d(0) { }
// Copy constructor.
B& operator=(const B& b_) {
a = b_.a;
b = b_.b;
c = b_.c;
d = b_.d;
return *this;
}
B& operator+=(const B& b_) {
a += b_.a;
b += b_.b;
c += b_.c;
d += b_.d;
return *this;
}
};
unsigned size;
B* b;
public:
A() : size(0) { }
// Copy constructor.
A(const A& a) : size(a.size) {
b = new B[size];
for (unsigned i = 0; i < size; ++i) {
b[i] = a[i];
}
}
// Copy assigment
A& operator=(const A& a) {
clear();
b = new B[size];
for (unsigned i = 0; i < size; ++i) {
b[i] = a[i];
}
return *this;
}
B& operator[](unsigned pos) const {
if (pos > size) {
throw std::out_of_range("Out of range");
}
return b[pos];
}
A operator+(const A& a) const {
A tmp = *this;
if (size != a.size) {
throw std::out_of_range("Diferent sizes");
}
for (unsigned i = 0; i < a.size; ++i) {
tmp[i] += a[i];
}
return tmp;
}
void read(const char* file) {
clear();
size = size_;
b = new B[size];
/*
* Read your file and update b.
*/
}
void clear() {
if (size) {
delete[] b;
size = 0;
}
}
~A() {
clear();
}
};