C中的内存分配问题[关闭]

Posted

技术标签:

【中文标题】C中的内存分配问题[关闭]【英文标题】:Problems with memory allocation in C [closed] 【发布时间】:2021-11-27 08:16:09 【问题描述】:

我是 C 语言的新手,我尝试编写函数来为二维数组分配内存 我在做什么:

void allocate(int **arr, int r, int c) 

    **arr = (int **)malloc(r*c*sizeof(int));

    int main( void )

    int NO_OF_COLS = 0;
    int NO_OF_ROWS = 0;    
    scanf("%d%d", &NO_OF_ROWS, &NO_OF_COLS);

    int **matrix;
    
    allocate(matrix, NO_OF_ROWS, NO_OF_COLS);

    return 0;

我有这个警告:从 'int **' 赋值给 'int' 使指针从没有强制转换的整数 [-Wint-conversion] 8 | **arr = (int **)malloc(rcsizeof(int)); | ^

我知道我在 allocate() 中将内存传递给“矩阵”,但我不明白如何返回新的内存地址并将其分配给矩阵

我尝试将allocate(matrix, NO_OF_ROWS, NO_OF_COLS); 更改为allocate(&matrix, NO_OF_ROWS, NO_OF_COLS);,但还是不行

【问题讨论】:

使用 2 颗星并不能简单地为您提供 2D 矩阵。如果你想要一个单一的分配,那么你需要一个一维数组并自己找出索引。如果是二维数组,那么您首先需要分配一个指针数组,然后每个指针分配一个一维数组。 您需要分配一维指针数组,其中的每个条目将是另一个一维整数数组 你可能想要int (*matrix)[NO_OF_COLS] = malloc(NO_OF_ROWS * sizeof *matrix); 这能回答你的问题吗? Correctly allocating multi-dimensional arrays 【参考方案1】:

由于您无法修改allocate 的参数,因此您需要手动计算矩阵中每个元素的索引。下面的基本程序展示了如何访问5 x 5 矩阵的每个元素。

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

void allocate(int **arr, int r, int c)

        *arr = malloc(sizeof (int) * r * c); 


int main(void)

        int *arr = NULL;
        int NO_OF_ROWS = 5, NO_OF_COLS = 5;
        allocate(&arr, NO_OF_ROWS, NO_OF_COLS);

        for (int r = 0; r < NO_OF_ROWS; ++r) 
              for (int c = 0; c < NO_OF_COLS; ++c) 
                    printf("arr[%d]\n", r * NO_OF_COLS + c); 
                 
           

这里,我们实际上使用的是一维数组。在循环内部,r * NO_OF_COLS + c 负责访问每个元素。该程序将打印arr[0]arr[1]...arr[24]。您可以使用此逻辑来计算每个元素的索引。

main() 内部,arr 只是一个指向int 的指针。当我们将arr地址 传递给allocate() 时,我们给allocate() 一个修改arr 的机会。然后,在allocate() 内部,我们跳转到传入的地址并放置malloc 返回的位。

【讨论】:

【参考方案2】:

首先,您需要分配一个数组数组来保存数据。您需要分配一个数组来保存 N 个指针类型的元素。考虑一下:

int** allocate(int row, int col)

    int i;
    int** a = (int**) malloc(row * sizeof(int*));
    if (!a)
        return  0;

    for(i=0; i < row; i++) 
        a[i] = (int*) malloc(sizeof(int) * col);
    
    return  a;

您需要分配a 来保存指向int 数组的N 个元素,然后在您的用例中循环并分配所需的实际数组(sizeof(int) * col)。 所以这里是用的:

int main()

    int** a= allocate(10, 10);
    int i=0, j=0;
    for(i=0; i < 10; i++) 
        for(j=0; j < 10; j++) 
            a[i][j] = 42;
        
    

    for(i=0; i < 10; i++) 
        for(j=0; j < 10; j++) 
            printf("[%d]", a[i][j]);
        
        puts("");
    
    return 0;

您还需要以相同的方式编写释放函数,但首先您必须循环遍历所有元素并释放数组,然后再释放 a 数组。 [编辑]:为简单起见,我没有在第二个 malloc 中添加故障安全检查。 鉴于该示例和该函数原型,您需要将一维数组分配为:

void allocate(int** a, int row, int col)

    *a = malloc(sizeof(int) * row * col);

但这与分配数组的数组不同。

【讨论】:

在分配时我无法更改函数 allocate() 的类型 如果这是一些家庭作业或练习,您可以使用我的作为助手在原来的内部调用。 void allocate(int** a, int row, int col) a = allocate_internal(row, col); ... 但在执行此类任务或练习之前,您最好了解 C 分配。 鉴于您的示例,我建议您需要分配一个大小为行 x col 的一维整数数组,这与二维数组不同。我认为在您的情况下,您只需要分配:void allocate(int** a, int row, int col) *a = malloc(sizeof(int) * row * col); 这不是二维数组而是一维数组。

以上是关于C中的内存分配问题[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

char的C风格转换后的不同内存分配[关闭]

什么是嵌入式系统的好 C 内存分配器? [关闭]

内存分配中的幻数[关闭]

C中结构中的指针-如何将给定的void指针的值分配给结构中的指针[关闭]

C中的指针:分配内存与赋值VS分配内存而不赋值

C语言中的动态内存分配的用法举例