Инициализация 2d логического массива в c ++ - PullRequest
5 голосов
/ 10 ноября 2011

Я не так часто использую C, и недавно я запутался в проблеме инициализации 2d-массива.Мне нужно отладить чей-то код и вставить следующее (ее исходный код):

const int location_num = 10000;
bool **location_matrix;
if (node_locations)
    {
        location_matrix = (bool **)malloc(location_num*sizeof(bool *));
        if (!location_matrix)
        {
                cout<<"error 1 allocating location_matrix" << endl;
                exit;
        }
        for (i=0; i<location_num; i++)
        {
                location_matrix[i] = (bool *) malloc(location_num*sizeof(bool ));
                if (!location_matrix[i])
                {
                        cout<<"error 2 allocating location_matrix" << endl;
                        exit;
                }
                for (j=0; j<location_num; j++)
                        location_matrix[i][j] = false;
        }
    }

Я думал, что это избыточно, поэтому я изменил его на следующее:

location_matrix[location_num][location_num] = { {false} };

Однако ошибка сегментации происходит во время выполнения.Мой вопрос: как вышеприведенный код не работает?Если все выглядит правильно, в чем разница между динамическим и статическим размещением?Это просто потому, что измерение может быть не постоянным, поэтому нам нужно делать это динамически?Кроме того, просто для любопытства, как мне разместить массив 2d, в котором хранятся указатели?Спасибо.

Ответы [ 4 ]

4 голосов
/ 10 ноября 2011

Для изменения, вероятно, потребуется около 100 МБ (10,000 * 10,000 * 1) в стеке, поэтому ошибка сегментации, вероятно, была вызвана переполнением стека.

Редактировать Я изначально указал 400МБ в ответе, но @Mooing Duck указывает, что bool, вероятно, будет 1 байт. Я думал о Win32 BOOL (безо всякой реальной причины), который определен как int.

2 голосов
/ 11 ноября 2011

Стандартная библиотека - ваш друг.

#include <vector>

int
main()
{
  int location_num = 1000;
  std::vector<std::vector<bool> > location_matrix(location_num, std::vector<bool>(location_num, false));
}
2 голосов
/ 10 ноября 2011

Я на самом деле не вижу ничего плохого в коде.

Следующий код не работает, потому что location_matrix не выделен:

location_matrix[location_num][location_num] = { {false} };

GCC разрешит следующее (как расширение):

bool location_matrix[location_num][location_num] = { {false} };

Но это взорвет ваш стек, потому что 10000 x 10000 слишком велик.

В настоящее время ваш код использует динамическое размещение. Это правильный способ сделать это, потому что матрица слишком велика, чтобы ее можно было использовать как статический массив (и может переполнить стек).

Что касается вашего последнего вопроса, «как создать 2d-массив, в котором хранятся указатели»: это можно сделать почти так же, как ваш текущий код. Просто измените bool на int*.

Таким образом, двумерный массив указателей NULL int будет выглядеть следующим образом:

int ***location_matrix;
if (node_locations)
{
    location_matrix = (int***)malloc(location_num*sizeof(int**));
    if (!location_matrix)
    {
            cout<<"error 1 allocating location_matrix" << endl;
            exit;
    }
    for (i=0; i<location_num; i++)
    {
            location_matrix[i] = (int**) malloc(location_num*sizeof(int*));
            if (!location_matrix[i])
            {
                    cout<<"error 2 allocating location_matrix" << endl;
                    exit;
            }
            for (j=0; j<location_num; j++)
                    location_matrix[i][j] = NULL;
    }
}
1 голос
/ 10 ноября 2011

Во-вторых, массив, вероятно, слишком велик для размещения в стеке, поэтому вам нужно его динамически распределять - но вы можете упростить код до тех пор, пока разница между 2-мерным массивом и массив указателей не будет проблемой (как если бы вам нужно было передать массив в функцию или использовать арифметику с указателями).

Вы можете использовать что-то вроде этого:

bool (*location_matrix)[location_num];

location_matrix = (bool (*)[location_num])calloc( location_num, 
                                                  location_num * sizeof(bool) );

... который выделяет пространство для всего двумерного массива и дает указатель на массив bool массивов с location_num элементами в каждом.

...