By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,406 Members | 888 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,406 IT Pros & Developers. It's quick & easy.

_CrtIsValidHeapPointer Debug Assertion

P: 2
Hi...

So I'm writing some code that does some matrix operations (namely multiplications) I've created a separate class for manipulating the matrices. The matrix itself has memory for it allocated within the class. Here's a sample of what I'm talking about...

Expand|Select|Wrap|Line Numbers
  1. Matrix* Matrix::multiply(const Matrix &b) {
  2.   assert(c == b.r);
  3.   Matrix *result = new Matrix(r, b.c);
  4.   for (int i = 0; i < b.c; i++)
  5.     for (int j = 0; j < r; j++)
  6.       for (int k = 0; k < c; k++)
  7.         result->matrix[i][j] += matrix[i][k] * b.matrix[k][j];
  8.   return result;
  9. }
The Constructor... Allocates a two dimensional array of type double, which can be referenced using array[i][j] notation.

Expand|Select|Wrap|Line Numbers
  1. Matrix::Matrix(int _r, int _c) {
  2.   r = _r;
  3.   c = _c;
  4.   matrix = (double**)malloc(r*sizeof(double*));
  5.   for (int i = 0; i < r; i++) {
  6.     matrix[i] = (double*)malloc(c*sizeof(double));
  7.     memset(matrix[i], 0x00, c*sizeof(double));
  8.   }
  9. }
The Destructor - frees allocated memory

Expand|Select|Wrap|Line Numbers
  1. Matrix::~Matrix() {
  2.   for (int i = 0; i < r; i++)
  3.     free(matrix[i]);
  4.   free(matrix);
  5. }
And the code that calls it...

Expand|Select|Wrap|Line Numbers
  1. Matrix a(3,1);
  2. Matrix b(3,3);
  3. Matrix *r = NULL;
  4.  
  5. //values fo the matrix are initialized here...
  6.  
  7. r = b.multiply(a);
  8. r->print();
  9. delete r;       //source of error...
  10.  
So it compiles and runs under linux, and GDB doesn't catch an error, and there is no error when multipling a 3x2 by a 2x3 matrix...also, sometimes the program will exit normally (the error doesn't happen all the time, more like about 90% of the time...

I'm flustered, thanks in advance to anyone that has suggestions!
Jun 27 '06 #1
Share this Question
Share on Google+
2 Replies


Banfa
Expert Mod 5K+
P: 8,916
I can see nothing obviously wrong, however I would not use the memory allocation technique you have.

Just because the data represents a matrix which is a 2 dimensional array does not mean you have to allocate it like that. For a 2 by 3 matrix all you actually need is space to store 6 doubles. This makes the constructor and destructor (obviously with a redefinition of matrix to type double *)

Expand|Select|Wrap|Line Numbers
  1. Matrix::Matrix(int _r, int _c) {
  2.   r = _r;
  3.   c = _c;
  4.   matrix = (double*)malloc(r*c*sizeof(double));
  5.   memset(matrix, 0x00, r*c*sizeof(double));
  6. }
  7.  
  8. Matrix::~Matrix() {
  9.   free(matrix);
  10. }
  11.  
As you can see the memory allocation is a lot simpler and has the added benafit of causing less memory fragmentation.

Next you add an inline member function in the header file a bit like

Expand|Select|Wrap|Line Numbers
  1.     inline int index(int i, int j) {
  2.         return i*c+j;
  3.     }
  4.  
then

Expand|Select|Wrap|Line Numbers
  1. /* instead of */
  2.  
  3. matrix[i][j] = ...;
  4.  
  5. /* use */
  6.  
  7. matrix[index(i,j)] = ...;
  8.  
This is a common technique for handling comples indexes, you can build various shape and dimension arrays this way.

On to you problem I believe it lies at least partly in this code

Expand|Select|Wrap|Line Numbers
  1. Matrix* Matrix::multiply(const Matrix &b) {
  2.   assert(c == b.r);
  3.   Matrix *result = new Matrix(r, b.c);
  4.   for (int i = 0; i < b.c; i++)
  5.     for (int j = 0; j < r; j++)
  6.       for (int k = 0; k < c; k++)
  7.         result->matrix[i][j] += matrix[i][k] * b.matrix[k][j];
  8.   return result;
  9. }
  10.  
In matrix[i][k] i and k have the wrong range for matrix, k 0 to c-1 may be ok but i 0 to b.c-1 does not necessarily have the same range as 0 to r-1.
Jun 27 '06 #2

P: 2
Thanks Banfra...I'll have to try that.

What baffles me about the problem is that it compiles and runs under linux...and produces proper output for larger matrices (i.e. 3x2 multiplied by a 2x3). It's the visual studio compiler that causes it to crash, and not even all the time....

For example, I just ran it now, and it did the multiplication and returned a correct result... Running a second time caused the debug assertion (on the same dataset)...

I'll try your fixes though and see if that helps.
Jun 27 '06 #3

Post your reply

Sign in to post your reply or Sign up for a free account.