我正在创建一个int数组和一个重载()运算符的类的实例。这是班级:
模板 类CMatrix { 公共:
CMatrix(const int d);
CMatrix(const int d1, const int d2);
CMatrix(const CMatrix<M> &old); // copy ctor
~CMatrix();
int getXSize() {return s1;}
int getYSize() {return s2;}
CMatrix<M>& operator=(const CMatrix<M> &cm);// Asgnmnt constructor
CMatrix<M>& operator*(CMatrix<M> &cm);
inline M& operator()(const int i) {
ASSERT1(i<s1 && i>=0);
printf("CMatrix::operator(): i=%d, s1=%d\n", i, this->s1);
return m[i];
}
inline M& operator()(const int i, const int j) {
ASSERT2(i<s1 && j<s2);
ASSERT2(i>=0 && j>=0);
return m[i*s2+j];
}
int s1, s2; // dimensions of array
M *m; // pointer to first element of matrix.
int dimensions;
宣言:
int *oldRow=NULL;
CMatrix<int> *useRow=NULL;
以下是它们的定义方式:
oldRow = new int(nNodes);
useRow = new CMatrix<int>(nNodes);
我有一个循环来初始化它们:
printf(": &oldRow[0]=%u\n", oldRow);
printf(": &oldRow[7]=%u\n", &oldRow[7]);
printf(": &(useRow->s1)=%u\n", &(useRow->s1));
printf(": &(useRow->m)=%u\n", &(useRow->m));
for (int i=0; i<nNodes; i++) {
*(oldRow+i)=99;
printf("A: s1=%d\n",(*useRow).s1);
printf("B: i=%d\n", i);
(*useRow)(i)=0;
printf("C: i=%d\n", i);
for (int j=0; j<nNodes; j++) nonZeroCount(i,j)=0;
}
最后,这是输出。看看s1被覆盖:
: &oldRow[0]=39846784
: &oldRow[7]=39846812
: &(useRow->s1)=39846800
: &(useRow->m)=39846808
A: s1=8
B: i=0
CMatrix::operator(): i=0, s1=8
C: i=0
A: s1=8
B: i=1
CMatrix::operator(): i=1, s1=8
C: i=1
A: s1=8
B: i=2
CMatrix::operator(): i=2, s1=8
C: i=2
A: s1=8
B: i=3
CMatrix::operator(): i=3, s1=8
C: i=3
A: s1=99
B: i=4
CMatrix::operator(): i=4, s1=99
我知道这有点复杂;我尽量让它变得尽可能简单,但仍保留所有相关细节。 我正在使用第二个普通的旧int数组来使用useRow但是我遇到了随机崩溃所以我认为我会使用我的CMatrix类。
无论如何,请注意输出顶部的地址 - useRow-&gt; s1和useRow-&gt; m放在oldRow数组的中间!
我知道我一定做错了,但我不知道它是什么。我也使用了std :: class,但是这些也随机崩溃了,我虽然int * oldRow可能不那么容易出错...
答案 0 :(得分:1)
oldRow = new int(nNodes);
由此我怀疑oldRow
的类型是指向int
的指针。上面的行将此指针设置为指向单个整数,并将其初始化为nNodes
的值。
你可能意味着像
oldRow = new int[nNodes]{};
// ^ ^ \
// array C++11 default init of the elements
实际上,当您以后访问&#34;元素&#34; oldRow
,您正在调用未定义的行为:通过在该元素的边界之外写入&#34;数组&#34;,您将覆盖堆中的其他内容,破坏堆并修改其他已分配的内容数据(在这种情况下,如果您的类,该实例的成员字段)。
我也在使用std :: class,但同时也遇到了随机崩溃,我虽然int * oldRow可能不太容易出错......
一般情况下,除非确实需要,否则您不应该像上面那样使用原始分配的数组。 std::vector
类为运行时大小的数组提供了更好的方法。如果它随机崩溃,那么这就是你做错事的直接迹象。