2010-06-26 4 views
2

Это вопрос с вопросом, который вчера задали мой друг. Вопрос был примерно такой: произойдет ли сбой программы с ошибкой «нарушение прав доступа» или нет? Я посмотрел на него некоторое время и не подумал, что нет. Но на самом деле попробовать это в визуальной студии оказалось не так. Я не могу понять, что здесь происходит ... или, если быть более точным, я знаю, что происходит, но не понимаю ПОЧЕМУ. Проблема заключается в том, что массив matrix2 вообще не выделяется.Проблема с распределением двухмерных массивов

код ниже:

#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; 
} 
+0

, что ужасающий беспорядок кода. Это для интервью на С ++? – stinky472

+0

Я считаю, что это так. Что так ужасно? – PeterK

ответ

4

Вы передаете двойной указатель «matrix2» по значению. Поэтому, когда matrixAlloc завершает свое дело, «matrix2» все равно будет тем, чем он был до вызова функции. Для того, чтобы получить изменения, чтобы заселить, рассмотреть вопрос о принятии matrix2 по ссылке:

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

Не забудьте изменить реализацию matrixAlloc разыменовать matrix2 при необходимости.

EDIT: Простое решение ниже. Измените эту строку:

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

к этому:

void matrixAlloc(int**& matrix, const int rows, const int cols) 
+0

Спасибо. Так просто. Не могу поверить, что я этого не видел! – PeterK

1
matrixAlloc(matrix2, 4, 5); 

Здесь вы передаете matrix2 по значению.

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

И здесь вы назначаете формальный параметр. Фактический параметр, который вы передали, не зависит от этого. Вероятно, вы должны передать параметр по ссылке:

void matrixAlloc(int**& matrix, const int rows, const int cols) 
+0

Yeesh, скопируйте мой ответ много? –

+0

@wowus: LOL, * вы * скопировали передав указатель по ссылке * от меня *. Или, возможно, у нас была одна и та же идея в одно и то же время. Как Ньютон и Лейбниц :) – fredoverflow

+0

Dibs on newton :) –

Смежные вопросы