【问题标题】:2d boolean array initialization in c++C ++中的二维布尔数组初始化
【发布时间】:2011-12-26 09:51:18
【问题描述】:

我不太会使用 C,最近我对二维数组初始化问题感到困惑。我需要调试某人的代码并坚持以下(她的原始代码):

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} };

但是,分段错误发生在运行时。 我的问题是:上面的代码是如何失败的?如果看起来正确,那么动态分配和静态分配有什么区别?只是因为维度可能不是恒定的,所以我们需要动态地做吗? 另外,只是为了好奇,我如何 malloc 存储指针的二维数组?谢谢。

【问题讨论】:

  • 你为什么用malloc(n * sizeof(T))而不是new T[n]

标签: c++ initialization multidimensional-array


【解决方案1】:

更改可能需要堆栈上大约 100MB (10,000 * 10,000 * 1),因此分段错误可能是由于堆栈溢出。

编辑我最初在答案中说 400MB,但@Mooing Duck 指出 bool 可能是 1 个字节。我在想 Win32 BOOL(根本没有真正的原因),它被定义为 int。

【讨论】:

  • 我不知道c,但是c++中内存不足时,系统会打印“bad alloc”,那你是说segmentation fault也可以代表c中的堆栈溢出?
  • 这取决于编译器,但堆栈上的“分配”基本上是堆栈指针的加法(或减法......我现在忘记它通常是上升还是下降)。如果没有启用堆栈检查,那么任何越过有效堆栈的对该局部变量的读/写操作都将访问有效地址空间之外的内存,这可能会导致分段错误。
  • @MarkWilkins:我认为(在大多数实现中)布尔值只有 1 个字节。不过,StackOverflow 似乎很有可能。
  • @Mooing Duck:这可能是真的。我会编辑它。我是基于 Win32 BOOL(没有充分理由)的,它是 4 个字节。
【解决方案2】:

我实际上没有发现代码有任何问题。

以下代码不起作用,因为location_matrix 未分配:

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

GCC 将允许以下内容(作为扩展):

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

但它会破坏你的堆栈,因为10000 x 10000 太大了。

目前,您的代码使用动态分配。这是正确的做法,因为矩阵太大而无法作为静态数组完成(并且可能会超出堆栈)。

至于您的最后一个问题,“如何制作一个存储指针的二维数组”:它可以与您当前的代码几乎相同的方式完成。只需将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;
    }
}

【讨论】:

  • location_num 是编译时初始化的本地 const int 所以这段代码应该在 C++ 中工作(即使没有编译器扩展),除非我暂时感到困惑。
  • @KonradRudolph:我将数组初始化器称为 GCC 扩展。
  • 初始化程序在我看来也不错。现在,你当然是正确的大小。
【解决方案3】:

标准库是你的朋友。

#include <vector>

int
main()
{
  int location_num = 1000;
  std::vector<std::vector<bool> > location_matrix(location_num, std::vector<bool>(location_num, false));
}

【讨论】:

  • 请注意 vector 有问题 - 它不是真正的布尔数组。标准库专用于 vector ,因此它将位打包到动态位集的尝试中。如果您确实需要一个布尔数组,以便 .data() 为您提供指向 bool* 的指针,然后将 std::deque 放入其中。
【解决方案4】:

其次,数组可能太大而无法放入堆栈,因此您需要动态分配它——但您可以简化代码,只要difference between a 2-dimensional array and an array of pointers 不会成为问题(因为它如果您需要将数组传递给函数或对其使用指针运算)。

你可以这样使用:

bool (*location_matrix)[location_num];

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

...为整个二维数组分配空间,并提供指向bool 数组的指针,每个数组包含location_num 元素。

【讨论】:

    猜你喜欢
    • 2016-12-27
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 2012-11-29
    相关资源
    最近更新 更多