C++:重载运算符返回类时未分配指针被释放错误

问题描述 投票:0回答:1

我试图为我在 CPP 中创建的类重载 + 运算符,但每当我返回重载函数中定义的新类对象时,它都会给我错误:

a.out(48371,0x10374a600) malloc: *** error for object 0x7ff7bf6525a0: pointer being freed was not allocated
a.out(48371,0x10374a600) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6

我的类定义在我的程序的 .h 文件中(顶部有必要的#includes 和 using 语句):

class Matrix{
    public:
        Matrix(int);
        Matrix();
        ~Matrix();
        int getLength();
        float* getData();
        void readMatrix(string fileName);
        Matrix operator + (Matrix &trixIn) {
            Matrix matrix;
            float out1[trixIn.getLength()];                       
            
            float* dataA = trixIn.getData();
            float* dataB = data;

            for (int i = 0; i < trixIn.getLength(); i++){                 
                out1[i] = dataA[i] + dataB[i];         
            }

            matrix.length = trixIn.getLength();
            matrix.data = out1;
            // all this data up this point is correct when printed to the terminal

            return matrix;   // returning this to the main function brings up the error
        }
        void print();
    private:
        float *data;
        int length;
};

这是我要调用的主要函数的一部分(A 和 B 是另外两个先前定义的 Matrix 对象):

Matrix C = A + B;
cout << "A + B with overload" << endl;
C.print();

这是在 main() 中调用的 print() 函数:

void Matrix::print(){
    for (int i = 0; i < length; i++){
       cout << std::setw(8) << data[i];  
    }
    printf("\n");
}

它说一个被释放的指针没有分配,但我根本没有试图释放任何分配的数据——这个错误是什么意思,解决这个问题的好方法是什么?

抱歉,如果答案很明显,我只是刚刚从 C 切换到 C++,而且我从来没有完全掌握指针和正确的数据分配。感谢您的所有建议!

c++ class pointers operator-overloading dynamic-memory-allocation
1个回答
2
投票

错误在这里

float out1[trixIn.getLength()];
...
matrix.data = out1;

首先,这甚至不是合法的 C++。在 C++ 中,数组边界必须是常量,而

trixIn.getLength()
不是常量。这种构造被称为 可变长度数组 或 VLA,一些编译器接受它,但正如我所说,这不是合法的 C++,因此在某些编译器上,这段代码甚至无法编译。然而,它是合法的 C,这也许就是您使用它的原因。

话虽如此,即使在接受它的编译器上,这段代码也存在漏洞。 VLA

out1
仅存在于您编写的
operator +
中。一旦退出该函数,数组就会被销毁。但是您已经在
data
中存储了指向该数组的指针。因此,您的
Matrix
类留下了一个指向不再存在的数组的指针,这称为 dangling pointer,这会导致您的崩溃。在 C++ 中,您永远不能忽略对象的lifetime,很容易编写指向或引用不再存在的对象的代码。

这两个问题的解决方案是使用动态分配

float* out1 = new float[trixIn.getLength()]; 

因为内存是动态分配的,所以当函数退出时它不会被销毁并且避免了特定问题。

现在你可能有很多其他问题(我没有测试你的代码),你肯定有内存泄漏的问题(正如你所说的你从来没有释放任何内存)。但我想这个问题是未来的事。

© www.soinside.com 2019 - 2024. All rights reserved.