我正在尝试编写一个表示一组整数的类。这是一项家庭作业,但对于我的生活,我无法弄清楚这个问题。
在“IntSet”类中,我有两个私有变量;一个是指向数组的指针,另一个是数组的大小。我可以创建这个类的对象,它们按预期工作。但我有一个名为“join”的函数,它返回IntSet类的一个对象。它基本上将数组连接在一起,然后使用该数组创建返回的对象。
这是我的代码:
#include <iostream>
using namespace std;
class IntSet {
int * arrPtr;
int arrSize;
public:
//Default Constructor
IntSet() {
int arr[0];
arrPtr = arr;
arrSize = 0;
}
//Overloaded Constructor
IntSet(int arr[], int size) {
arrPtr = arr;
arrSize = size;
}
//Copy Constructor
IntSet(const IntSet &i) {
arrPtr = i.arrPtr;
arrSize = i.arrSize;
}
/*
* Returns a pointer to the first
* element in the array
*/
int* getArr() {
return arrPtr;
}
int getSize() {
return arrSize;
}
IntSet join(IntSet &setAdd) {
//Make a new array
int temp[arrSize + setAdd.getSize()];
//Add the the values from the current instance's array pointer
//to the beginning of the temp array
for (int i = 0; i < arrSize; i++) {
temp[i] = *(arrPtr + i);
}
//Add the values from the passed in object's array pointer
//to the temp array but after the previously added values
for (int i = 0; i < setAdd.getSize(); i++) {
temp[i + arrSize] = *(setAdd.getArr() + i);
}
//Create a new instance that takes the temp array pointer and the
//size of the temp array
IntSet i(temp, arrSize + setAdd.getSize());
//Showing that the instance before it passes works as expected
cout << "In join function:" << endl;
for (int j = 0; j < i.getSize(); j++) {
cout << *(i.getArr() + j) << endl;
}
//Return the object
return i;
}
};
int main() {
//Make two arrays
int arr1[2] = {2 ,4};
int arr2[3] = {5, 2, 7};
//Make two objects normally
IntSet i(arr1, 2);
IntSet j(arr2, 3);
//This object has an "array" that has arr1 and arr2 concatenated, essentially
//I use the copy constructor here but the issue still occurs if I instead use
//Inset k = i.join(j);
IntSet k(i.join(j));
//Shows the error. It is not the same values as it was before it was returned
cout << "In main function:" << endl;
for (int l = 0; l < k.getSize(); l++) {
cout << *(k.getArr() + l) << endl;
}
return 0;
}
程序编译,截至目前的输出为:
In join function:
2
4
5
2
7
In main function:
10
0
-2020743083
32737
-2017308032
我不知道为什么但每次重新编译和运行时10和0总是一样的。另外,如果我打印出指针的地址而不是值(在连接函数和主函数中),我得到相同的内存地址。
对不起,如果我滥用条款,我来自java背景,所以指针等对我来说有点新鲜。如果需要澄清,请询问。
提前致谢。
答案 0 :(得分:4)
int temp[arrSize + setAdd.getSize()];
这是一个本地数组,它的生命周期在函数返回后结束。
IntSet i(temp, arrSize + setAdd.getSize());
这里使用此数组构建IntSet
。实际上,构造函数只是将成员指针更改为temp
:
IntSet(int arr[], int size) {
arrPtr = arr;
arrSize = size;
}
因此,由于temp
并因此i.arrPtr
指向的对象的生命周期在离开join
后结束,因此您将拥有一个野指针。稍后在main
中取消引用此指针会调用未定义的行为。
您需要使用new[]
动态分配数组,然后使用delete[]
将其删除。你的构造函数也是如此。另请注意,如果在析构函数中使用new[]
和join
中的delete[]
,则还必须确保复制构造函数实际复制数组(使用{{1创建新数组)并复制内容)。如果只是分配指针,则源和目标对象都将指向同一个数组,并且它们也会在解构时尝试删除它,再次调用未定义的行为。
但是从这个C ++开始,你也可以使用new[]
来完成所有这些工作。 (或std::vector
如果你真的想要一个整数集
答案 1 :(得分:0)
您的代码最快的修复方法是更改
int temp[arrSize + setAdd.getSize()];
进入这个
int * temp = new int[arrSize + setAdd.getSize()];
问题是你在堆栈上分配了temp,所以当join()返回时,内存是release。通过在堆上分配内存(根据修复),当join()返回时,内存不会被释放。
您的代码还有其他问题 - 取决于分配点。我认为当你考虑在堆上有内存的含义时,大多数这些都将被修复。