【问题标题】:How to access elements in double pointer style matrix如何访问双指针样式矩阵中的元素
【发布时间】:2013-04-30 23:47:29
【问题描述】:
double **matrix = NULL;
matrix = (double **)malloc(sizeof(double *) * N);   // N is the size of the square matrix

for(int i=0; i<N; i++)
{
   matrix[i] = (double *)malloc(sizeof(double)*N);
}

// Works good up to the next part
for(int i=0; i<N; i++)
{
   for(int j=0; j<N; j++)
   {
      printf("Value: %f", matrix[i][j]);
   }
}

我正在尝试使用上述方法创建一个二维双精度数组(创建一个指针数组,然后每个指针获取一个双精度数组)。但是,一旦我尝试打印第一个元素 matrix[0][0],就会出现段错误。我看过其他一些几乎做同样事情的帖子,除了我不能让我的工作。

【问题讨论】:

  • 这是C还是C++?
  • 你的代码没问题。我们将需要查看一个 SSCCE (sscce.org) 来实际演示该问题。
  • (1) 不要转换malloc 的结果。这可能会抑制重要的编译器消息。 (2) 建立一个sscce
  • @borisbn:错了。你试过了吗?请注意,这是 C,而不是 C++。
  • 您尚未发布实际失败的程序。因此,没有人能说出它失败的原因。请记住,SSCCE 不仅仅是一个好主意,它还是法律。

标签: c pointers multidimensional-array matrix


【解决方案1】:

在语法方面,您的代码没有任何问题。要么你没有显示整个代码,要么(不太可能)程序内存不足,而你没有检查 malloc 的结果来了解这一点。

在程序设计方面,您不应该使用分段指针指向指针语法;它在整个堆中创建 N 个数组,而不是在相邻的内存单元中分配一个真正的 2D 数组。堆碎片对程序性能不利,并可能导致各种其他问题(取决于系统)。

在 C 中强制转换 malloc 的结果是没有意义的。在旧的 C 编译器上,它甚至是有害的。

在打印它们之前,您不要给数组的项目任何值。要将它们全部设置为零,请使用 memset 或将 malloc 替换为 calloc。

您应该修复上述问题并将您的代码重写为:

#include <stdlib.h>
#include <stdio.h>

double (*matrix)[N];  // an array pointer
matrix = calloc(1, sizeof(double[N][N])); // pointing at one true 2D array

if(matrix == NULL)
{
  // handle error
}


for(int i=0; i<N; i++)
{
  for(int j=0; j<N; j++)
  {
    printf("Value: %f", matrix[i][j]);
  }
}

【讨论】:

  • IIRC 标准不要求全位零内存模式对应于零(或任何有效)浮点值。虽然在实践中这通常 :-) 有效。
  • 感谢您的解决方案。如果我需要用户输入 N 怎么办?
  • @user2063561 没问题,C 支持变长数组,所以上面的数组指针可以创建变长。
【解决方案2】:

您好,我有这个 c++ 文件,它与 g++ 编译器一起运行良好。

#include <cstdio>
#include <cstdlib>

using namespace std;

int main(){
    int N = 10;
    double **matrix = NULL;
    matrix = (double **)malloc(sizeof(double *) * N);   // N is the size of the square matrix

    for(int i=0; i<N; i++)
    {
        matrix[i] = (double *)malloc(sizeof(double)*N);
    }

    for(int i=0; i<N; i++)
    {
        for(int j=0; j<N; j++)
        {
            printf("Value: %f", matrix[i][j]);
        }
    }
}

【讨论】:

  • 为什么using namespace std ??? 1) 这个命名空间没有在你的代码中使用 2) 这是 C 问题,不是 C++ !!
  • @borisbn 谢谢。这只是我编写c++的习惯……毕竟,你总是可以用c++的方式编译c……
  • “你总是可以用 c++ 方式编译 c” - 不。 C++ 不支持堆栈中的动态数组 - int N = 42; int array[ N ];。 C++ 不支持按名称初始化结构字段。 C++ 不支持从 void* 隐式转换为其他(如 n.m. 在 cmets 中所说)等。
  • 为什么要在 C++ 中使用 malloc 而不是 new(或向量,或智能指针)?没关系,因为这个答案是题外话,应该删除。
  • @hongtao (1) AFAIK 这是 C++ 的扩展,g++ 支持,但其他 (2) 不支持:struct struct_t struct_var = { .field1 = 42, .field10 = "abcde" };
猜你喜欢
  • 2016-07-13
  • 1970-01-01
  • 1970-01-01
  • 2022-10-24
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
相关资源
最近更新 更多