如何使函数返回动态分配的二维数组?

How to make a function returning a dynamically-allocated two-dimensional array?

我正在尝试 return 从一个函数中分配一个连续内存数组,但我一直收到错误。

编译器 return 警告说 return from incompatible pointer type [-Wincompatible-pointer-types]

谁能告诉我我做错了什么?

int *test() {
    size_t rows, cols;
    // assign rows and cols
    rows = 3;
    cols = 3;
    int count = 0;

    int (*arr)[cols] = malloc(sizeof *arr * rows);
    if (arr) {
        // do stuff with arr[i][j]
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; j++) {
                arr[i][j] = count;
                count++;
            }
            /* code */
        }
    }
    return arr;
}

int main() {    
    size_t rows, cols;
    // assign rows and cols
    rows = 3;
    cols = 3;
    int count = 0;

    int (*arr)[cols] = malloc(sizeof *arr * rows);
    arr = test();

    int i = 0;
    int j = 0;

    for (i = 0; i < rows; ++i) {
        for (j = 0; j < 3; ++j)
            printf("%d ", arr[i][j]);
        printf("\n");
    }
    free(arr);
}

它应该 return 一个二维数组,但 return 是一个错误,我在 ubuntu

上使用 gcc

你的分配函数很好,除了一些细节:

  • 你应该传递 rowscols 作为参数
  • 您应该为 ij 使用类型 size_t 并迭代到 rowscols 而不是硬编码边界。
  • 为了便于阅读,您应该在 malloc(sizeof *arr * rows); 中使用括号: malloc(sizeof(*arr) * 行);
  • 您应该 return &arr[0][0]arr[0] 以确保类型正确。

问题是您无法将 test 的 return 类型定义为 指向参数化第二维 的二维数组的指针。因此赋值 arr = test(); 的类型错误无法修复。您可以通过将 return 值转换为 (int (*)[cols]) 或简单地 (void *).

来解决这个缺点

这是修改后的版本:

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

int *test(size_t rows, size_t cols) {
    int (*arr)[cols] = malloc(sizeof(*arr) * rows);
    if (arr) {
        // initialize the matrix
        size_t count = 0;
        for (size_t i = 0; i < rows; i++) {
            for (size_t j = 0; j < cols; j++) {
                arr[i][j] = count;
                count++;
            }
            /* code */
        }
        return &arr[0][0];
    }
    return NULL;
}

int main() {
    // assign rows and cols
    size_t rows = 3;
    size_t cols = 3;

    int (*arr)[cols] = (int (*)[cols])test(rows, cols);

    if (arr) {
        for (size_t i = 0; i < rows; i++) {
            for (size_t j = 0; j < cols; j++)
                printf("%d ", arr[i][j]);
            printf("\n");
        }
        free(arr);
    }
    return 0;
}

输出:

0 1 2
3 4 5
6 7 8

如果全部你需要的是

to return a contiguous memory allocated array from a function

你可以忽略这个答案。

如果您要做的是使用动态分配的连续内存块为二维容器(如矩阵)建模,您可以定义一个 struct 并传递它:

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

typedef struct {
    int rows, cols;
    int values[];      // I'm using a Flexible Array Member here.
} iMat;

iMat *alloc_matrix(int rows, int columns)
{
    assert(rows > 0  &&  columns > 0);
    iMat *tmp = malloc(sizeof *tmp + sizeof *(tmp->values) * rows * columns);   
    if (tmp)
    {
        tmp->rows = rows;
        tmp->cols = columns;
    }
    return tmp;
}

void fill_matrix_iota(iMat *m, int start)
{
    if ( m )
        for (size_t i = 0, n = m->rows * m->cols; i < n; ++i)
            m->values[i] = start + i;
}

void print_matrix(iMat *m, int width)
{
    if (m)
    {
        for (int i = 0, k = 0; i < m->rows; ++i)
        {
            for(int j = 0; j < m->cols; ++j, ++k)
            {
                printf("%*.d", width, m->values[k]);
            }
            putchar('\n');
        }
    }
}

iMat *make_transposed(iMat *m)
{
    if ( !m )
        return NULL;
    iMat *tmp = alloc_matrix(m->cols, m->rows);
    if ( tmp )
    {
        for (int i = 0; i < m->rows; ++i)
        {
            for(int j = 0; j < m->cols; ++j)
            {
                tmp->values[j * m->rows + i] = m->values[i * m->cols + j];
            }
        }        
    }
    return tmp;
}

int main(void)
{    
    iMat *a = alloc_matrix(3, 4);
    if (!a)
        exit(EXIT_FAILURE);

    fill_matrix_iota(a, 1);
    print_matrix(a, 3);

    iMat *b = make_transposed(a);
    if (!b)
    {
        free(a);
        exit(EXIT_FAILURE);
    }
    putchar('\n');
    print_matrix(b, 3);

    free(b);
    free(a);

    return EXIT_SUCCESS;
}