我在使用c ++中的二维数组时遇到了一些内存问题。
摘自主要内容:
int **A,**B,**C;
A = new int*[d];
B = new int*[d];
C = new int*[d];
if (file.is_open()){
for (int i = 0; i < d ;i++){
A[i] = new int[d];
C[i] = new int[d];
for(int j = 0; j < d ;j++){
if(getline(file,line)){
A[i][j] = atoi(line.c_str());
}else{
cout<<"Dimension does not match inputfile.\n";
return(1);
}
}
}
for (int i = 0; i < d ;i++){
B[i] = new int[d];
for(int j = 0; j < d ;j++){
if(getline(file,line)){
B[i][j] = atoi(line.c_str());
}else{
cout<<"Dimension does not match inputfile.\n";
return(1);
}
}
}
file.close();
}
...
cout<<"A4\n";
PrintM(A,n);
AddMatrix(B,bi,bj,B,bi,bj+n/2,C,ci,cj,n/2);
cout<<"A5\n";
PrintM(A,n);
...
添加矩阵例程:
void AddMatrix(int** X,int ai,int aj,int** Y, int bi,int bj,int** Z,int ci,int cj,int n){
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
Z[i+ci][j+cj] = X[i+ai][j+aj] + Y[i+bi][j+bj];
}
PrintM例程:
void PrintM(int **P,int n){
for (int i=0;i<n;i++){
cout<<"[";
for (int j=0;j<n;j++){
if (j != n-1)
cout<<P[i][j]<<",";
else
cout<<P[i][j]<<"]\n";
}
}
cout<<endl;
}
输出:
A4
[0,0]
[0,0]
A5
[4,0]
[0,0]
我不知道为什么在AddMatrix例程中修改数组A,因为我甚至没有在例程调用中使用它。我还没有包含所有代码(300行),但我不能在一个简短的例子中重现这个问题。我没有像在任何地方说A = C那样愚蠢。我无法弄清楚我哪里出错了。
答案 0 :(得分:0)
书面缓冲区溢出
由于函数正在修改未传递给函数的其他数据,因此在写入时看起来像buffer overflow。函数中唯一的写入是
行Z[i+ci][j+cj] = X[i+ai][j+aj] + Y[i+bi][j+bj];
您正在Z
之外写入已分配/目的地为A
的内存中。你想在Z
内写,即你必须检查
0<=i+ci<DZ1
,DZ1
Z
0<=j+cj<DZ2
,DZ2
Z
现在,i
和j
都在循环中运行,最小0
和最大值n-1
。对于2
和i
的每个值,必须遵守j
不等式,因此我们获得
0<=ci<DZ1-(n-1)
,DZ1
Z
0<=cj<DZ2-(n-1)
,DZ2
Z
如果已知尺寸DZ1
和DZ2
,请考虑在assert
的开头添加AddMatrix()
,例如
assert(0<=ci<DZ1-(n-1) && "buffer overrun in the 1st dimension");
assert(0<=cj<DZ2-(n-1) && "buffer overrun in the 2nd dimension");
并在顶部添加#include<cassert>
。以上内容将解决A
在调用中更改的问题,其中A
甚至未作为参数传递。这是Z
中写的缓冲区溢出。
但是,您可能会在X
和Y
的读取中出现缓冲区溢出。这不会影响A
,你会发现你可能在开发的后期有一个bug。
如果您打算长时间或在大型项目中使用此代码,请添加更多断言,检查ai
,aj
,bi
,bj
的范围。
阅读中的缓冲区溢出
另一种可能是对象A
小于n
n
,当您打印A
时,实际上是C
的一部分打印。检查n
的大小是A
。
答案 1 :(得分:0)
感谢大家的答案,我在代码的不同部分发现了问题。我递归地调用了一个函数,其中A和C是同一个对象。 ** 手腕上的自拍 **