0

I am encountering some memory issues while working with a 2 dimensional array in c++.

Excerpt from main:

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);
...

The add matrix routine:

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];
}

The PrintM routine:

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;
}

And the output:

A4
[0,0]
[0,0]

A5
[4,0]
[0,0]

I have no idea why the array A is being modified in the AddMatrix routine, as I'm not even using it in the call to the routine. I haven't included all the code here (300 lines long), but I couldn't recreate the problem in a short example. I'm not doing anything silly like saying A = C anywhere. I can't figure out where I'm going wrong.

Matt Pennington
  • 560
  • 1
  • 8
  • 21
  • put a data breakpoint on the single value that you know has changed and should not. also, use valgrind – v.oddou Mar 27 '14 at 05:06
  • You problem is probably in the code you didn't include. How are `A` and `B` initialized? – agbinfo Mar 27 '14 at 05:09
  • this AddMatrix(B,bi,bj,B,bi,bj+n/2,C,ci,cj,n/2); is for matrix A5 i think. What you are passing for matrix A4?? – Himanshu Mar 27 '14 at 05:14
  • I agree with @agbinfo. Offhand, it looks like a buffer overrun may be the culprit. – Lilshieste Mar 27 '14 at 05:26
  • You have omitted the definition of B and C. Without that information, any answers here are as authoritative as the press giving causes for the Malaysian Airplane Disaster. This is one possible cause http://stackoverflow.com/questions/9446707/correct-way-of-passing-2-dimensional-array-into-a-function – user3344003 Mar 27 '14 at 05:46

2 Answers2

0

Buffer overflow in writing

As the function is modifying other data not passed to the function, this looks like a buffer overflow in writing. The only write in the function is in the line

Z[i+ci][j+cj] = X[i+ai][j+aj] + Y[i+bi][j+bj];

You are writing outside Z, in the memory allocated/destined for A. You want to write inside Z, i.e. you must check that

  • 0<=i+ci<DZ1, with DZ1 of the 1st dimension of Z
  • 0<=j+cj<DZ2, with DZ2 of the 2nd dimension of Z

Now, both i and j are run in a loop and have minimum 0 and maximum value n-1. The 2 inequalities must be respected for every value of i and j, so we obtain

  • 0<=ci<DZ1-(n-1), with DZ1 of the 1st dimension of Z
  • 0<=cj<DZ2-(n-1), with DZ2 of the 2nd dimension of Z

If the sizes DZ1 and DZ2 are known, consider adding an assert at the beginning of AddMatrix(), like

assert(0<=ci<DZ1-(n-1) && "buffer overrun in the 1st dimension");
assert(0<=cj<DZ2-(n-1) && "buffer overrun in the 2nd dimension");

and add #include<cassert> at the top. The above will solve the problem you have with A changing in a call where A was not even passed as argument. This was a buffer overflow in writing in Z.

However, you may also have a buffer overflow in reading from X and Y. This would not affect A, and you would realize you have a bug possibly much later in the development.

If you plan on using this code for long time or in a large project, add more asserts checking the bounds of ai,aj,bi,bj.

Buffer overflow in reading

The other possibility is that the object A is smaller then n by n, and when you print A you are actually printing part of C. Check that n is the size of A.

gg349
  • 21,996
  • 5
  • 54
  • 64
0

Thanks for the answers everyone, I found the problem in a different part of the code. I was recursively calling a function where A and C were the same object. **Slaps self on wrist**

Matt Pennington
  • 560
  • 1
  • 8
  • 21
  • LOL... that happens. So - just to let you know - this question now probably won't help anybody else if they have a similar issue. What generally happens now is that we vote to close it. So don't take it personal when that happens - it's just to make sure that questions will answers are what stick around in the S/O community. :) – Taryn East Mar 28 '14 at 02:45
  • 1
    Taryn, I would vote to close this question too. No offense taken. – Matt Pennington Mar 28 '14 at 02:55
  • @MattPennington, I don't see how this can explain the error presented above. Good that you somehow sorted it out anyway. – gg349 Mar 28 '14 at 12:14