【问题标题】:Pointer to a 2D dynamic Array Pointer指向 2D 动态数组指针的指针
【发布时间】:2017-02-07 09:59:43
【问题描述】:

如何创建指向以下二维数组指针 int **arr 的指针。我正在寻找类似于 int*** arr 及其分配、释放、访问和使用的东西。

int main()
{
  int** arr;

  int row = 11;
  int col = 2;
  int i,j;

  arr = (int**)malloc(sizeof(int*)*row);
  for (i=0; i<row; ++i){
    arr[i] = (int*)malloc(sizeof(int)*col);
  }

  for (i = 0; i < row; i++) {
    for (j = 0; j < col; j++) {
        arr[i][j] = i;
        printf("arr[%d][%d] : %d\n",i,j,arr[i][j]);
    }
  }

  return 0;
}

以前的参考资料:

动态二维数组指针:

C programming initialize 2D array dynamically

指向动态二维数组的指针,但这里的解释是使用 new 关键字,我想使用 malloc 代替:

How to allocate a 2D array of pointers in C++

其他信息:

考虑以下场景:

XYZ* arr[A][B];

“XYZ”是自定义数据类型, “A”和“B”是运行时的动态变量

在这种情况下,我们如何在运行时定义 A & B 并使用 XYZ* 类型访问 arr[A][B] 元素值。

【问题讨论】:

  • 对于指向arr 的指针,您需要成为three-star programmer,并且被称为通常不是恭维。
  • 什么是“动态数组”?分配在动态内存中的数组还是具有随时可能变化的可变维度的数组?正确答案很大程度上取决于你想要哪一个。
  • 如果您只是想动态分配一个二维数组,那么它应该是int (*arr)[row] = malloc(sizeof(int[col][row])); 就是这样。不需要指针对指针的指针...
  • 为什么你需要一个三星指针?您尝试通过使用解决的实际问题是什么?如果您想要一个动态数组数组(指向指针really isn't),那么您已经拥有了它。为什么需要添加另一个间接级别?
  • 请在问题中找到添加的附加信息。

标签: c pointers multidimensional-array


【解决方案1】:

进一步了解答案,您会发现更多可能的解决方案。

首先,我想向您介绍一个解决方案,您可以使用一维指针管理一个动态二维数组,以防列长度相同。

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

struct XYZ
{
    int someValue;
};

struct XYZ* GetArrayItem(struct XYZ* itemArray, int numCols, int row, int col)
{
    return &itemArray[row * numCols + col];
}

int main()
{
    int A = 5;
    int B = 4;
    struct XYZ* arr = (struct XYZ*)calloc(A*B, sizeof(struct XYZ));

    for (int i = 0; i < A; i++)
    {
        for (int j = 0; j < B; j++)
        {
            GetArrayItem(arr, B, i, j)->someValue = 1;
        }
    }

    free(arr);

    return 0;
}

对于不同长度的列,双指针可能是一个可行的解决方案。

struct XYZ
{
    int someValue;
};

int main()
{
    int i;
    int j;
    // row count
    int A = 5;
    // column count per row
    int B[] = { 3, 4, 3, 2, 4 };
    struct XYZ** arr = (struct XYZ**)calloc(A, sizeof(struct XYZ*));
    for (i = 0; i < A; i++)
    {
        // initialize column for each row
        arr[i] = (struct XYZ*)calloc(B[i], sizeof(struct XYZ));
    }

    for (i = 0; i < A; i++)
    {
        for (j = 0; j < B[i]; j++)
        {
            // access items
            arr[i][j].someValue = 1;
        }
    }

    for (i = 0; i < A; i++)
    {
        free(arr[i]);
    }

    free(arr);

    return 0;
}

但是,如果您需要二维数据,我建议您创建一个更明确的对象结构。这使得设计更加明确,每行的列数更加透明。

struct XYZ
{
    int someValue;
};

struct MyDomainSpecificRow
{
    int numColumns;
    struct XYZ* myRowData;
};

int main()
{
    int i;
    int j;
    // row count
    int A = 5;
    // column count per row
    int B[] = { 3, 4, 3, 2, 4 };
    // 1d array of rows, each containing 1d array of cells
    struct MyDomainSpecificRow* arr = (struct MyDomainSpecificRow*)calloc(A, sizeof(struct MyDomainSpecificRow));

    for (i = 0; i < A; i++)
    {
        // initialize column for each row
        arr[i].numColumns = B[i];
        arr[i].myRowData = (struct XYZ*)calloc(B[i], sizeof(struct XYZ));
    }

    for (i = 0; i < A; i++)
    {
        for (j = 0; j < arr[i].numColumns; j++)
        {
            // access items
            arr[i].myRowData[j].someValue = 1;
        }
    }

    for (i = 0; i < A; i++)
    {
        free(arr[i].myRowData);
    }

    free(arr);

    return 0;
}

【讨论】:

    【解决方案2】:

    解决方案: 最后,我设法得到了我想要的东西。

    声明:

    NodeClass* currentNode;     //Single Pointer Declaration
    NodeClass*** triplePtrNode; //Triple Pointer Declaration
    

    定义与分配:

    //row, col are dynamic values at runtime
    
    //row memory allocation
    triplePtrNode = (NodeClass***)malloc(sizeof(NodeClass)*row); 
    for (i=0; i<row; ++i){
        //col memory allocation
        triplePtrNode[i] = (NodeClass**)malloc(sizeof(NodeClass)*col); 
    }
    

    用法:

    for (i=0; i<memberCounts; ++i){
        *(*(triplePtrNode+i)+0) = currentNode->member1;
        *(*(triplePtrNode+i)+1) = currentNode->member2;
    }
    

    【讨论】:

    • 在 C 或 C++ 中没有正确使用三重指针。它们仅在树星编程的分支中有用。与其试图成为树星程序员,不如专注于解决实际问题。您为任务选择了错误的解决方案的可能性很大。
    • 是的,我同意。我想在您的评论中添加以下内容:MISRA-C:2004 17.5“对象的声明应包含不超过 2 级的指针间接” MISRA C++ 2008 5-0- 19 对象的声明应包含不超过两级的指针间接。
    • 使用指向一维数组的指针数组的二维数组的效率远低于使用一些算法来进行正确索引的一维数组。也不能保证内存会被连续布局,这也可能是一个问题。
    猜你喜欢
    • 1970-01-01
    • 2012-03-09
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    相关资源
    最近更新 更多