c++ - 我的数组值如何被覆盖

标签 c++ arrays overwrite

我正在创建一个整数数组和一个重载 () 运算符的类的实例。这是类(class):

模板 C矩阵类 { 公共(public):

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

我知道这有点复杂;我试图让它尽可能简单,但仍然保留了所有相关细节。 我为 useRow 使用了第二个普通的旧 int 数组,但我遇到了随机崩溃,所以我想我应该改用我的 CMatrix 类。

无论如何,请注意输出顶部的地址 - useRow->s1 和 useRow->m 正好放在 oldRow 数组的中间!

我知道我一定做错了什么,但我不知道是什么。我也为他们两个都使用了 std::class 但也遇到了随机崩溃,我虽然 int *oldRow 可能不太容易出错......

最佳答案

oldRow = new int(nNodes);

据此我怀疑 oldRow 的类型是指向 int 的指针。上面的行将此指针设置为指向一个单个 整数,并将其初始化为nNodes 的值。

你的意思可能是这样的

oldRow = new int[nNodes]{};
//              ^      ^  \
//               array   C++11 default init of the elements

事实上,当您稍后访问 oldRow 的“元素”时,您将调用未定义的行为:通过在该元素“数组”的边界之外写入,您将覆盖其他元素堆中的东西,破坏你的堆并修改其他分配的数据(在这种情况下,如果你的类是该实例的成员字段)。

I also was using std:: class for both of them but was getting random crashes with those as well, I though int *oldRow might be less error-prone...

一般来说,除非真的需要,否则你不应该像上面那样使用原始分配的数组。 std::vector 类为运行时大小的数组提供了更好的方法。如果它随机崩溃,那么这是您做错事情的直接信号。

关于c++ - 我的数组值如何被覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32021970/

相关文章:

c++ - _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)) 错误

c++ - 使用weak_ptr的观察者模式

c++ - 设置 -fno-elide-constructors 时,clang Xcode 4.4.1 是否存在错误?

python - 循环以最小化python中数组的功能

c# - DataTable 覆盖上一行

Javascript/jQuery : nesting loops, 防止覆盖对象属性

C++11 正则表达式细节

arrays - 如何使用Go将这个JSON数组解码到结构 slice 中?

python - 使用 python 的 long 类型的 numpy 数组

linux - "ln -sf"不覆盖目录的符号链接(symbolic link)