views:

90

answers:

2

Hello all,

this is an interview question my friend was asked yesterday. The question was something like: will this program crash with an "access violation" error or not? I looked at it for a while and thought no, it won't. But actually trying this out in visual studio proved me wrong. I cannot figure out what happens here... or to be more precise, i know what happens, but do not understand WHY. The problem seems to be that the matrix2 array does not get allocated at all.

Code below:

#include <iostream>
#include <ctime>

using namespace std;

int** matrixAlloc( const int rows, const int cols );
void matrixAlloc( int** matrix, const int rows, const int cols );
void matrixDealloc( int** m, const int rows);
void matrixPrint( const int* const * const m, const int rows, const int cols );

int main( int argc, char** argv )
{   
    srand( (unsigned int)time( NULL ) );
    int** matrix1 = matrixAlloc( 4, 5 );
    matrixPrint( matrix1, 4, 5 );
    matrixDealloc( matrix1, 4 );

    int ** matrix2 = NULL;
    matrixAlloc( matrix2, 4, 5 );
    matrixDealloc( matrix2, 4 ); // <--- crash occurs here  
}

int** matrixAlloc( const int rows, const int cols )
{
    int **matrix = new int *[ rows ];
    for ( int i = 0; i < rows; i++ )
    {
        matrix[ i ] = new int[ cols ];
        for ( int j = 0; j < cols; j++ )
        {
            matrix[ i ][ j ] = (rand() * 12347) % 10;
        }
    }

    return matrix;
}

void matrixAlloc( int** matrix, const int rows, const int cols )
{
    matrix = new int *[ rows ];
    for ( int i = 0; i < rows; i++ )
    {
        matrix[ i ] = new int[ cols ];
        for ( int j = 0; j < cols; j++ )
        {
            matrix[ i ][ j ] = (rand() * 12347) % 10;
        }

    }
}

void matrixDealloc( int** matrix, const int rows )
{       
    for ( int i = 0; i < rows; i++ )
    {
        delete [] matrix[ i ];
    }
    delete [] matrix;
}

void matrixPrint( const int* const * const matrix, const int rows, const int cols )
{
    for ( int i = 0; i < rows; i++ )
    {
        for ( int j = 0; j < cols; j++ )
        {
            cout << matrix[ i ][ j ] << " ";
        }
        cout << endl;
    }
    cout << endl;
}
+1  A: 
matrixAlloc( matrix2, 4, 5 );

Here you are passing matrix2 by value.

void matrixAlloc( int** matrix, const int rows, const int cols )
{
    matrix = new int *[ rows ];

And here, you are assigning to a formal parameter. The actual parameter that you passed in is not affected by that. You should probably pass the parameter by reference:

void matrixAlloc( int**& matrix, const int rows, const int cols )
FredOverflow
Yeesh, copy my answer much?
Clark Gaebel
@wowus: LOL, *you* copied passing the pointer by reference *from me*. Or, we just might have had the same idea at the same time. Like Newton and Leibnitz :)
FredOverflow
Dibs on newton :)
Clark Gaebel
+4  A: 

You are passing the double pointer "matrix2" by value. Therefore, when matrixAlloc finishes doing its thing, "matrix2" will still be whatever it was before the function was called. In order to get the change to populate, consider passing matrix2 by reference:

int** matrix2 = NULL;
matrixAlloc(&matrix2, 4, 5);
...

Don't forget to change the implementation of matrixAlloc to dereference matrix2 when necessary.

EDIT: Simple solution below. Change this line:

void matrixAlloc( int** matrix, const int rows, const int cols )

to this:

void matrixAlloc( int**& matrix, const int rows, const int cols )
Clark Gaebel
Thanks. As simple as that. Cannot believe i didnt see it!
PeterK