C:使用函数

时间:2016-03-13 22:05:38

标签: c arrays dynamic-memory-allocation

我希望max的内容为tmp_maxmax是动态分配的。 tmp_max大小已知。

当我对其进行硬编码时,复制值正常工作,但在创建复制值的函数时它不起作用。那是为什么?

//This code works
int** max;
init2D(&max,3,4);

int tmp_max[3][4] = {{3,3,2,2}, {1,2,3,4}, {1,3,5,0}};

for(int i = 0 ; i < 3; i++)
    for(int j = 0 ; j < 4; j++)
        max[i][j] = tmp_max[i][j];

assert(max[0][1] == 3); 
//This one crashes
void copyArray2D(int a, int b, int*** tab,int*** tab2){
    for(int i = 0 ; i < a; i++)
        for(int j = 0 ; j < b; j++)
            tab2[i][j] = tab[i][j];
}

int** max;
init2D(&max,3,4);

int tmp_max[3][4] = {{3,3,2,2}, {1,2,3,4}, {1,3,5,0}};
copyArray2D(3,4,&tmp_max,&max); //crash

assert(max[0][1] == 3);

注意:

使用void copyArray2D(int a, int b, int** tab,int** tab2){copyArray2D(3,4,max,tmp_max);也无效。

使用void copyArray2D(int a, int b, int** tab,int** tab2){copyArray2D(3,4,&max,&tmp_max);也无效。

void init2D(int ***data_ptr, int x, int y) {
    int **data = (int **) malloc(sizeof(int *) * x);
    for (int k = 0; k < x; k++)
        data[k] = (int *) malloc(sizeof(int) * y);
    *data_ptr = data;
}

3 个答案:

答案 0 :(得分:2)

您的编译器应该抱怨copyArray2D(3,4,&tmp_max,&max)

在尝试运行代码之前,必须修复编译器发现的任何问题(根据损坏的代码运行任何此类可执行文件都没有意义)。

一个问题是copyArray2Dint***时应该说int**

修复之后,这里的主要问题是你已经写了copyArray2D,所以它只适用于一组指针。 (您通过分配指针数组来模拟二维数组,然后使每个指针指向代表每一行的单独分配。)

当您使用init2D时,这是有效的,因为init2D函数会分配指针数组等。

然而int tmp_max[3][4]是一个由12个连续的整数组成的块。没有指针。这与copyArray2D不兼容。

您的选择是:

  • 使用int **tmp_max并使用init2D进行分配,而不是int tmp_max[3][4]
  • 制作另一个copyArray2D版本,该版本适用于连续的二维数组。
  • 使用丑陋的宏

答案 1 :(得分:1)

你的第二个功能有太多的星星。当我第一次写回答时你没有显示init2D函数,所以我不得不猜测你用它做了什么(但代码现在在问题中,并且与我生成的代码相近,即差异是无关紧要的 - 除了我做错误检查分配)。这是代码的(重写)版本(第一个版本没有在编译器附近,我完全错过了一个关键的细节)。请注意,int **int arr[N][M]或主题的变体不同 - 即使您使用相同的表示法来访问这两者。

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

static void copyArray2D(int a, int b, int **dst, int src[a][b])
{
    for (int i = 0; i < a; i++)
        for (int j = 0; j < b; j++)
            dst[i][j] = src[i][j];
}

static void oom(void)
{
    fprintf(stderr, "Out of memory\n");
    exit(1);
}

static void init2D(int ***arr, int a, int b)
{
    (*arr) = malloc(a * sizeof((*arr)[0]));
    if (*arr == 0)
        oom();
    for (int i = 0; i < a; i++)
    {
        (*arr)[i] = malloc(b * sizeof((*arr)[0][0]));
        if ((*arr)[i] == 0)
            oom();
    }
}

static void dump_2d_array(int a, int b, int arr[a][b])
{
    for (int i = 0; i < a; i++)
    {
        for (int j = 0; j < b; j++)
            printf(" %2d", arr[i][j]);
        putchar('\n');
    }
}

static void dump_2d_pointers(int a, int b, int **arr)
{
    for (int i = 0; i < a; i++)
    {
        for (int j = 0; j < b; j++)
            printf(" %2d", arr[i][j]);
        putchar('\n');
    }
}

int main(void)
{
    int **max;
    init2D(&max, 3, 4);

    int tmp_max[3][4] = { { 3, 3, 2, 2 }, { 1, 2, 3, 4 }, { 1, 3, 5, 0 } };
    copyArray2D(3, 4, max, tmp_max);
    printf("2D array:\n");
    dump_2d_array(3, 4, tmp_max);
    printf("List of pointers:\n");
    dump_2d_pointers(3, 4, max);
    return 0;
}

运行该代码的输出:

2D array:
  3  3  2  2
  1  2  3  4
  1  3  5  0
List of pointers:
  3  3  2  2
  1  2  3  4
  1  3  5  0

请注意,我没有编写自由函数,因此内存泄露了。

警惕3-Star Programming

答案 2 :(得分:0)

void copyArray2D(int a, int b, int tab[a][b],int*** tab2){
    for(int i = 0 ; i < a; i++)
        for(int j = 0 ; j < b; j++)
            (*tab2)[i][j] = tab[i][j];
}

copyArray2D(3,4,tmp_max,&max);