【问题标题】:Create 2D array by passing pointer to function in c通过将指针传递给c中的函数来创建二维数组
【发布时间】:2016-08-13 04:14:29
【问题描述】:

所以我阅读了几十个将二维数组指针传递给函数以在函数中获取/更改该数组值的示例。但是是否可以在函数内部创建(分配内存)。像这样的:

#include <stdio.h>

void createArr(int** arrPtr, int x, int y);

int main() {

    int x, y;       //Dimension
    int i, j;       //Loop indexes
    int** arr;      //2D array pointer
    arr = NULL;
    x=3;
    y=4;

    createArr(arr, x, y);

    for (i = 0; i < x; ++i) {
        for (j = 0; j < y; ++j) {
            printf("%d\n", arr[i][j]);
        }
        printf("\n");
    }
    _getch();    
}

void createArr(int** arrPtr, int x, int y) {
    int i, j;       //Loop indexes
    arrPtr = malloc(x*sizeof(int*));
    for (i = 0; i < x; ++i)
        arrPtr[i] = malloc(y*sizeof(int));

    for (i = 0; i < x; ++i) {
        for (j = 0; j < y; ++j) {
            arrPtr[i][j] = i + j;
        }
    }    
}

【问题讨论】:

  • 您的代码中没有数组指针,也没有任何二维数组。
  • @Martin 你能告诉我怎么做吗?
  • @Lundin 好的,所以有指向 int 的指针,但它可以用作指向 2Dim 数组的指针,对吧?
  • @Marcin 不,它不能。这是一个常见的错误,您一直在从不良资源中学习。我会发布一个答案。

标签: c arrays function pointers malloc


【解决方案1】:

忘记指针对指针。它们与二维数组无关。

如何正确操作:How do I correctly set up, access, and free a multidimensional array in C?.

使用指针到指针是错误的众多原因之一:Why do I need to use type** to point to type*?。

如何正确执行的示例:

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


void* create_2D_array (size_t x, size_t y)
{
  int (*array)[y] = malloc( sizeof(int[x][y]) );

  for (size_t i = 0; i < x; ++i) 
  {
    for (size_t j = 0; j < y; ++j) 
    {
      array[i][j] = (int)(i + j);
    }
  }

  return array;
}

void print_2D_array (size_t x, size_t y, int array[x][y])
{
  for (size_t i = 0; i < x; ++i) 
  {
    for (size_t j = 0; j < y; ++j) 
    {
      printf("%d ", array[i][j]);
    }
    printf("\n");
  }
}


int main (void)
{
  size_t x = 5;
  size_t y = 3;

  int (*arr_2D)[y];

  arr_2D = create_2D_array(x, y);

  print_2D_array(x, y, arr_2D);

  free(arr_2D);

  return 0;
}

【讨论】:

  • 当我尝试使用您的版本时,它说: size_t y 表达式必须具有恒定值。所以你不能动态地制作这样的数组(正如我所说的......)
  • @Marcin 我确实编译并测试了这段代码。您必须使用 1999 年之后制作的编译器(为什么不呢?)。例如海合会。您可以使用编译器选项gcc -std=c11 -pedantic-errors 告诉 GCC 成为 C 编译器。
  • 我今天一整天都想不通。从您的示例接缝中的所有内容都可以正常工作,但我无法弄清楚这一点。如果我按函数print2DArray(xDim, yDim, arr); 打印表格,我会得到所有元素,所以它工作正常。如果我打印一个像 printf( "%d\n", arr[0][0]) 这样的元素就可以了。但是,如果我像这样打印printf( "%d\n",old[1][1]); 或任何其他不同于 0 的值,则会出现分段错误。请帮帮我。
  • @Marcin 什么是“旧”?
  • 对不起。 “old”是我在代码中使用的数组名称,但在这里我将其粘贴为arr。所以应该是printf( "%d\n",arr[1][1])。名称在代码中很好。
【解决方案2】:

是的,传递一个指向 int ** 的指针(但 3 星被认为是不好的风格),我建议从你的函数中返回一个分配的变量:

int **createArr(int x, int y)
{
    int **arrPtr;
    int i, j;       //Loop indexes

    arrPtr = malloc(x*sizeof(int*));
    if (arrPtr == NULL) { /* always check the return of malloc */
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    for (i = 0; i < x; ++i) {
        arrPtr[i] = malloc(y*sizeof(int));
        if (arrPtr[i] == NULL) {
            perror("malloc");
            exit(EXIT_FAILURE);
        }
    }
    for (i = 0; i < x; ++i) {
        for (j = 0; j < y; ++j) {
            arrPtr[i][j] = i + j;
        }
    }
    return arrPtr;   
}

调用它使用:

arr = createArr(x, y);

【讨论】:

  • 你应该检查malloc的所有返回值,而不仅仅是第一个。
  • 没有理由创建分段的指针对指针的东西。相反,当您需要 2D 数组时,请使用 2D 数组。
  • Soo.. 我可以这样做: void createArr(int*** arrPtr, int x, int y);这里 arrPtr 是一个指向 **int 的指针,它可以包含数组的地址。但它看起来很糟糕。另一种更优雅的方式是您展示的方式。非常感谢您的快速解答!
  • @Marcin 看起来很糟糕,因为它很糟糕。您不应该首先使用任何指针到指针。你应该使用真正的二维数组,假设二维数组是你想要的。
  • @Lundin 但是我必须动态创建这个数组(不知道运行前的维度),所以我必须这样做。
【解决方案3】:

是的,可以通过这种方式初始化数组。只要您传递一个指针,内存地址就应该保持不变。因此,如果您为指针分配任何内容,它将有效。

将 a[] 视为指向第一个元素的 a* 指针

a [][] 将是一个**指向第一个元素的指针或指向第一个数组(表的第一行)的指针

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 2014-05-09
    • 2018-12-08
    • 1970-01-01
    • 2014-07-29
    相关资源
    最近更新 更多