I have the following class:
我有以下课程:
class Patient {
public:
Patient(int x);
~Patient();
private:
int* RP;
};
Patient::Patient(int x) { RP = new int [x]; }
Patient::~Patient() { delete [] RP; }
I create an instance of this class on the stack as follows:
我在堆栈上创建了这个类的实例,如下所示:
void f() { Patient p(10); }
Now, when f()
returns, I get a "double free or corruption" error, which signals to me that something is attempted to be deleted more than once. But I don't understand why that would be so. The space for the array is created on the heap, and just because the function from inside which the space was allocated returns, I wouldn't expect the space to be reclaimed.
现在,当f()返回时,我得到一个“double free或corruption”错误,这向我表明某些内容试图多次删除。但我不明白为什么会这样。数组的空间是在堆上创建的,仅仅因为分配空间的函数返回,我就不会期望空间被回收。
I thought that if I allocate space on the heap (using the new
keyword), then the only way to reclaim that space is to use the delete keyword. Help!
我认为如果我在堆上分配空间(使用新的关键字),那么回收该空间的唯一方法就是使用delete关键字。的帮助!
As requested, here is the actual code (slightly abridged for brevity's sake)
按照要求,这里是实际的代码(为了简短起见,略作删减)
Here's the full class definition (split across a .cpp
and .h
file, but shown together):
这里是完整的类定义(在.cpp和.h文件中拆分,但同时显示):
class Patient {
public:
Patient(int numDecisionEpochs);
~Patient();
void recordRP(const int& age, const bool& t);
void recordBiopsy(const int& age, const int& result);
void recordPSA(const int& age, const double& level);
void recordPSA(const int& age);
private:
int* RP;
int* Biopsy;
double* PSA;
};
Patient::Patient(int numDecisionEpochs) {
RP = new int [numDecisionEpochs];
Biopsy = new int [numDecisionEpochs];
PSA = new double [numDecisionEpochs];
}
Patient::~Patient() {
delete[] RP;
}
void Patient::recordRP(const int& age, const bool& t) {
if(t)
RP[age-1] = 1; // RP either yes (1) or no (0)
else
RP[age-1] = 0;
}
void Patient::recordBiopsy(const int& age, const int& result) {
switch(result)
{
case 0:
case 1:
case 2:
case 3:
case 4:
Biopsy[age-1]=result; // only permit results 0,1,2,3,4
break;
default:
cerr << "Invalid biopsy result (" << result << ") at age " << age << "!\n";
}
}
void Patient::recordPSA(const int& age, const double& level) {
PSA[age-1] = level; // record PSA volume
}
void Patient::recordPSA(const int& age) {
PSA[age-1] = -1; // symbol for no screening during epoch
}
Next, the function where the above class is used. The following function is called directly from main()
and passed a Policy
object which is completely independent and separate from the Patient
class:
接下来,使用上述类的函数。下面的函数直接从main()调用,并传递一个完全独立于Patient类的策略对象:
void simulate1(Policy& P)
{
// ...
Patient patient(260);
for(int idx=0; idx<(P.size); idx++)
{
while(state != 9) // while patient not dead
{
// ...
patient.recordPSA(age,PSA);
// ...
patient.recordPSA(age);
// ...
patient.recordBiopsy(age,biopsyResult);
// ...
patient.recordRP(age,true);
// ...
patient.recordRP(age,false);
// ...
} // end patient (while loop)
} // end sample (for loop)
} // end function
3 个解决方案
#1
7
You're violating the rule-of-three (or for C++11, the rule-of-five). You need a copy constructor and copy-assignment operator that does a deep copy of the pointer. Of course, since you don't track the size of the array you allocate, this isn't possible without introducing a second data member.
您违反了三规则(或者对于c++ 11,即五规则)。您需要一个复制构造函数和复制赋值操作符,该操作符会对指针进行深入的复制。当然,由于不跟踪所分配的数组的大小,因此不引入第二个数据成员是不可能的。
#2
2
This doesn't answer your question directly, but also consider using std::vector.
这并不能直接回答您的问题,但也可以考虑使用std::vector。
#3
0
There is nothing in any of the record...
methods that bounds checks the age. So, if age happens to be greater than 260
or less than 0
in your example, you will write past the bounds of either RP
or Biopsy
or PSA
. That leads directly to a "double free or corruption" error.
没有任何记录……界限检查年龄的方法。所以,如果你的例子中年龄大于260或小于0,你会写超过RP或活检或PSA的界限。这直接导致了“双重*或腐败”的错误。
#1
7
You're violating the rule-of-three (or for C++11, the rule-of-five). You need a copy constructor and copy-assignment operator that does a deep copy of the pointer. Of course, since you don't track the size of the array you allocate, this isn't possible without introducing a second data member.
您违反了三规则(或者对于c++ 11,即五规则)。您需要一个复制构造函数和复制赋值操作符,该操作符会对指针进行深入的复制。当然,由于不跟踪所分配的数组的大小,因此不引入第二个数据成员是不可能的。
#2
2
This doesn't answer your question directly, but also consider using std::vector.
这并不能直接回答您的问题,但也可以考虑使用std::vector。
#3
0
There is nothing in any of the record...
methods that bounds checks the age. So, if age happens to be greater than 260
or less than 0
in your example, you will write past the bounds of either RP
or Biopsy
or PSA
. That leads directly to a "double free or corruption" error.
没有任何记录……界限检查年龄的方法。所以,如果你的例子中年龄大于260或小于0,你会写超过RP或活检或PSA的界限。这直接导致了“双重*或腐败”的错误。