2016-03-20 5 views
2

Я работаю над 2D-массивом на C++. У меня возникают проблемы с подключением понятий массивов и указателей. Я знаю, что они связаны с распределением памяти и доступом к элементам. НапримерC++ - Инициализация 2D-массива с нотной меткой

int *arr; 
int num = arr + 1*sizeof(int); 

такая же, как

int arr[]; 
int num = arr[1]; 

Я пытаюсь найти такую ​​же связь между 2D массивов и указателей Вот мой код

void printGrid(int **arr) { 
for (int i = 0; i < 10; i++) { 
    for (int j = 0; j < 10; j++) { 
    cout << setw(3); 
    cout << arr[i][j] << " "; 
    } 
    cout << endl; 
} 
} 

int main() { 
int **grid; 
srand(time(NULL)); 
for (int i = 0; i < 10; i++) { 
    for (int j = 0; j < 10; j++) { 
    grid[i][j] = rand() % 11; 
    } 
} 
printGrid(grid); 
} 

Когда я компилирую это, он компилируется. Когда я попытаюсь запустить его, я получаю segfault. Может ли кто-нибудь указать на ошибку в моем коде?

Благодаря SO

+2

"int num = arr + 1 * sizeof (int);" это не то же самое, что и arr [1]. –

+2

нет памяти, выделенной для ** сетки. Это всего лишь указатель. выделить место для него или установить его на определенный размер, например. malloc или объявить int grid [10] [10]; – user5976242

+1

В вашем коде нет 2D-массива. У вас есть указатель на указатель, что совсем другое. – juanchopanza

ответ

3
int **grid; 
srand(time(NULL)); 
for (int i = 0; i < 10; i++) { 
    for (int j = 0; j < 10; j++) { 
    grid[i][j] = rand() % 11; 
    } 
} 

Где та часть, которая должна выделить память для динамического массива? И, возможно, также для его элементов? Чтобы исправить это, вы могли бы сделать

// Allocating memory for array and elements 
int **grid = new int*[10]; 
for (int i = 0; i < 10; i++) { 
    grid[i] = new int[10]; 
} 
// Now fill the array as you had in your code 
// 
... 
// Deletion part 
for (int i = 0; i < 10; i++) { 
    delete[] grid[i]; 
} 
delete[] grid; 

Кроме того,

Я работаю на 2D массива в C++. У меня возникли проблемы с подключением концепций массивов и указателей . Я знаю, что они связаны в терминах элементов распределения и доступа к памяти. Например

int * arr; int num = arr + 1 * sizeof (int);

такое же, как

int arr []; int num = arr [1];

Нет, они не то же самое. Это было бы то же самое, хотя:

int x[] = {0, 2, 3}; 
int *arr = x; 
int num = *(arr + 1); //Look up pointer arithmetic; same as num=arr[1]; 
+0

Хорошо. Понимаю. Как именно я выделяю память для 2D-массива? –

+0

@Q_A см. Обновление –

1

grid является неинициализированным указатель. Попытка сохранить что-либо через этот указатель приведет к неопределенному поведению, например, к отказу сегментации.

Ваш код должен был бы выглядеть следующим образом:

grid = new (int*) [10]; 
for (int i = 0; i < 10; i++) { 
    grid[i] = new int[10]; 
    for (int j = 0; j < 10; j++) { 
     grid[i][j] = rand() % 11; 
    } 
} 

(И вы должны delete память вы выделенную когда вы закончили)

for (int i = 0; i < 10; i++) { 
    delete[] grid[i]; 
} 
delete[] grid; 
+0

Спасибо. Просто последующий вопрос, если не возражаете, как мне удалить этот двумерный динамически распределенный массив. Я знаю, что для переменных без массива мне нужно написать delete var; и для массивов я должен написать delete [] arr; Как сделать то же самое с 2D-массивом? Спасибо –

+0

@Q_A Обновлено с кодом удаления. – AJNeufeld

1

Одна большая разница между int ** ptrptr и int arr[X][Y] что ptrptr является указателем на указатель int, поэтому он может содержать переменную длину указателей int, каждая из которых может представлять массивы различного размера l IKE:

ptrptr (ptrptr points to the beginning of three different sized arrays) ▼ address_1: 0 1 2 3 address_2: 4 5 address_3: 6 7 8

Для переменной arr, то occuppies массив непрерывной памяти, и, таким образом, он может быть визуализированы в виде прямоугольника, так что думать о нем, как каждая строка должна иметь одинаковое число элементов.

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