返回后重写数组的内容

Content of array being rewritten after return

本文关键字:数组 重写 返回      更新时间:2023-10-16

首先,我有以下类A,同时具有嵌套类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成员的内容来使用重载的+操作员来"添加"两个A对象,并将结果分配给第三个A对象。

  • bB对象的intainmatial分配阵列。

  • B是一个相当基本的类,只有一些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 )

这是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;
    }
}

和类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,当调试时,我观察到:

  1. b result的成员指向 in [1] 指向的同一地址> 当复制构造函数由 [2] 的返回语句调用时,到目前为止很好

  2. 直到中的返回[2] b的内容是正确的,例如:0x00669968 00 00 ff 00 00 ff 00 00 ..ÿ..ÿ..

  3. [3] 中的b的内容[1] ,因此result CC_21对象的b成员的内容变成了:0x00669968 dd dd dd dd dd dd dd dd ÝÝÝÝÝÝÝÝ,I'm猜测是垃圾

注意:所有include代码的指令和无关的部分均已

我已经摇了摇头两天,试图弄清楚没有运气的问题,所以对任何帮助都非常感谢,谢谢。

我检查您的代码,问题是您需要class A的自定义复制分配。在您的主体中,您有A a1, a2, result;,默认构造函数用于3个对象。然后,在result = a1 + a2;行中,默认副本分配被调用。

当您在课堂上有指针并使用新的记忆分配记忆时,您必须担心复制构造函数和复制分配。检查此帖子和三个规则。


我建议您下一个代码:

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();
    }
};