C语言 2D 数组内存分配并传递给函数



我正在编写这个程序来打印正方形,立方体,4的倍数,5的倍数到二维数组中。我总是收到分段错误错误。你能帮忙解释一下发生了什么吗?程序不会打印 2D 数组的所有元素。它以第 4 行或第 6 行之后的分段错误结束。

#include<stdio.h>
#include<stdlib.h>
void numbers(int ***arr,int nrows,int ncols);
void square(int ***arr,int nrows,int ncols);
void cube(int ***arr,int nrows,int ncols);
void multiples_of_4(int ***arr,int nrows,int ncols);
void multiples_of_5(int ***arr,int nrows,int ncols);
void free_our_ptr(int ***arr,int nrows,int ncols);

int main(void)
{
    int i=0;
    int nrows = 0;
    int ncols = 0;
    int menu_choice = 0;
    int **arr;
    printf("nGet number of rows : ");
    scanf("%d",&nrows);
    if(nrows > 10)
    {
        printf("nRows should be less than 10 ");
        exit(0);
    }
    printf("nGet number of columns : ");
    scanf("%d",&ncols);
    if(ncols > 10)
    {
        printf("nColumns should be less than 10 ");
        exit(0);
    }
    /******* Dynamic memory allocation for array ***********/
    arr = (int **) malloc ( nrows * sizeof(int));
    for(i=0;i<nrows;i++)
    {
        arr[i] = (int *) malloc ( ncols * sizeof(int));
    }
    /********************************************************/
    printf("nThese are your choices : ");
    printf("nFill with Integers ---------------- 1");
    printf("nFill with Squares  ---------------- 2");
    printf("nFill with Cubes ------------------- 3");
    printf("nFill with Multiples of 4 ---------- 4");
    printf("nFill with Multiples of 5 ---------- 5");
    printf("nnEnter your choice : ");
    scanf("%d",&menu_choice);
    switch(menu_choice)
    {
    case 1:
        numbers(&arr,nrows,ncols);
        break;
    case 2:
        square(&arr,nrows,ncols);
        break;
    case 3:
        cube(&arr,nrows,ncols);
        break;
    case 4:
        multiples_of_4(&arr,nrows,ncols);
        break;
    case 5:
        multiples_of_5(&arr,nrows,ncols);
        break;
    default :
        printf("nInvalid Choice, exiting program");
        free(arr);
        exit(0);
    }
    exit(0);
}
void numbers(int ***array,int nrows,int ncols)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    arr = *array;
    for(i=0;i<nrows;i++)
    {
        printf("n");
        for(j=0;j<ncols;j++)
        {
            arr[i][j] = number;
            printf("%dt",arr[i][j]);
            number++;
        }
    }
    free_our_ptr(&arr,nrows,ncols);

}
void square(int ***array,int nrows,int ncols)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    arr = *array;
    for(i=0;i<nrows;i++)
    {
        printf("n");
        for(j=0;j<ncols;j++)
        {
            arr[i][j] = number * number;
            printf("%dt",arr[i][j]);
            ++number;
        }
    }
    free_our_ptr(&arr,nrows,ncols);
}

void cube(int ***array,int nrows,int ncols)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    arr = *array;
    for(i=0;i<nrows;i++)
    {
        printf("n");
        for(j=0;j<ncols;j++)
        {
            arr[i][j] = number * number * number;
            printf("%dt",arr[i][j]);
            number++;
        }
    }
    free_our_ptr(&arr,nrows,ncols);
}
void multiples_of_4(int ***array,int nrows,int ncols)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    arr = *array;
    for(i=0;i<nrows;i++)
    {
        printf("n");
        for(j=0;j<ncols;j++)
        {
            arr[i][j] = number * 4;
            printf("%dt",arr[i][j]);
            number++;
        }
    }
    free_our_ptr(&arr,nrows,ncols);
}
void multiples_of_5(int ***array,int nrows,int ncols)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    arr = *array;
    for(i=0;i<nrows;i++)
    {
        printf("n");
        for(j=0;j<ncols;j++)
        {
            arr[i][j] = number * 5;
            printf("%dt",arr[i][j]);
            number++;
        }
    }
    free_our_ptr(&arr,nrows,ncols);
}
void free_our_ptr(int ***arr,int nrows,int ncols)
{
    int i;
    for(i=0;i<nrows;i++)
    {
        free(arr[i]);
    }
    free(arr);
}

我尝试了这些建议,完全删除了 free_our_ptr() 函数并释放了 main() 本身的内存。在 ubuntu linux gcc 上,它给出了一个分段错误错误。但是,在Visual Studio-Windows7上,运行良好,在任何测试用例中都没有错误。下面是修改后的代码。

#include<stdlib.h>
void numbers(int ***arr,int nrows,int ncols);
void square(int ***arr,int nrows,int ncols);
void cube(int ***arr,int nrows,int ncols);
void multiples_of_4(int ***arr,int nrows,int ncols);
void multiples_of_5(int ***arr,int nrows,int ncols);
int main(void)
{
    int i=0;
    int nrows = 0;
    int ncols = 0;
    int menu_choice = 0;
    int **arr;
    printf("nGet number of rows : ");
    scanf_s("%d",&nrows);
    if(nrows > 10)
    {
        printf("nRows should be less than 10 ");
        exit(0);
    }
    printf("nGet number of columns : ");
    scanf_s("%d",&ncols);
    if(ncols > 10)
    {
        printf("nColumns should be less than 10 ");
        exit(0);
    }
    printf("nNumber of rows = %d",nrows);
    printf("nNumber of cols = %d",ncols);
    /******* Dynamic memory allocation for array ***********/
    arr = (int **) malloc ( nrows * sizeof(int));
    for(i=0;i<nrows;i++)
    {
        arr[i] = (int *) malloc ( ncols * sizeof(int));
    }
    /********************************************************/
    printf("nThese are your choices : ");
    printf("nFill with Integers ---------------- 1");
    printf("nFill with Squares  ---------------- 2");
    printf("nFill with Cubes ------------------- 3");
    printf("nFill with Multiples of 4 ---------- 4");
    printf("nFill with Multiples of 5 ---------- 5");
    printf("nnEnter your choice : ");
    scanf_s("%d",&menu_choice);
    switch(menu_choice)
    {
    case 1:
        numbers(&arr,nrows,ncols);
        break;
    case 2:
        square(&arr,nrows,ncols);
        break;
    case 3:
        cube(&arr,nrows,ncols);
        break;
    case 4:
        multiples_of_4(&arr,nrows,ncols);
        break;
    case 5:
        multiples_of_5(&arr,nrows,ncols);
        break;
    default :
        printf("nInvalid Choice, exiting program");
        free(arr);
        exit(0);
    }
    free(arr);
    exit(0);
}
void numbers(int ***array,int num_rows,int num_columns)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    int r1 = num_rows;
    int c1 = num_columns;
    arr = *array;
    printf("nNumber of rows = %d",r1);
    printf("nNumber of cols = %d",c1);
    for(i=0;i<r1;i++)
    {
        printf("n");
        for(j=0;j<c1;j++)
        {
            arr[i][j] = number;
            printf("%dt",arr[i][j]);
            number++;
        }
    }

}
void square(int ***array,int num_rows,int num_columns)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    int r2 = num_rows;
    int c2 = num_columns;
    arr = *array;
    printf("nNumber of rows = %d",r2);
    printf("nNumber of cols = %d",c2);
    for(i=0;i<r2;i++)
    {
        printf("n");
        for(j=0;j<c2;j++)
        {
            arr[i][j] = number * number;
            printf("%dt",arr[i][j]);
            ++number;
        }
    }
}

void cube(int ***array,int num_rows,int num_columns)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    int r3 = num_rows;
    int c3 = num_columns;
    arr = *array;
    printf("nNumber of rows = %d",r3);
    printf("nNumber of cols = %d",c3);
    for(i=0;i<r3;i++)
    {
        printf("n");
        for(j=0;j<c3;j++)
        {
            arr[i][j] = number * number * number;
            printf("%dt",arr[i][j]);
            number++;
        }
    }
}
void multiples_of_4(int ***array,int num_rows,int num_columns)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    int r4 = num_rows;
    int c4 = num_columns;
    arr = *array;
    printf("nNumber of rows = %d",r4);
    printf("nNumber of cols = %d",c4);
    for(i=0;i<r4;i++)
    {
        printf("n");
        for(j=0;j<c4;j++)
        {
            arr[i][j] = number * 4;
            printf("%dt",arr[i][j]);
            number++;
        }
    }
}
void multiples_of_5(int ***array,int num_rows,int num_columns)
{
    int i=0;
    int j=0;
    int number = 1;
    int **arr;
    int r5 = num_rows;
    int c5 = num_columns;
    arr = *array;
    printf("nNumber of rows = %d",r5);
    printf("nNumber of cols = %d",c5);
    for(i=0;i<r5;i++)
    {
        printf("n");
        for(j=0;j<c5;j++)
        {
            arr[i][j] = number * 5;
            printf("%dt",arr[i][j]);
            number++;
        }
    }
}
arr = (int **) malloc ( nrows * sizeof(int));

是不对的。它需要

arr = (int **) malloc ( nrows * sizeof(int*));
                                       ^^^^ an array of pointers to int.

第一个为nrows分配了足够的空间int
第二个为nrows分配足够的空间 int* s。

另外,由于您使用的是 C,而不是 C++,因此不要强制转换 malloc 的返回值。请参阅我是否投射 malloc 的结果?

只需使用:

arr = malloc ( nrows * sizeof(int*));

free_our_ptr的功能也不对。

void free_our_ptr(int ***arr,int nrows,int ncols)
{
    int i;
    for(i=0;i<nrows;i++)
    {
        free(arr[i]);
             ^^^^ Not right
    }
    free(arr);
         ^^^ Not right.
}

我的修复建议是将界面更改为:

void free_our_ptr(int **arr, int nrows, int ncols);
                      ^^^^ Use int**, not int***.

然后,函数中的代码将起作用。但是,您需要更改使用它的所有位置。

而不是将其称为:

free_our_ptr(&arr,nrows,ncols);

您需要将其称为:

free_our_ptr(arr,nrows,ncols);
             ^^^ No &

您将指针传递给指针,该指针引用为函数free_our_ptr分配的 dynminc 内存。要么取消引用函数内的指针:

void free_our_ptr(int ***arr,int nrows,int ncols)
{
    int i;
    for(i=0;i<nrows;i++)
    {
        free((*arr)[i]);
           // ^
    }
    free(*arr);
      // ^ type of arr is int***
}

或者将指向动态分配内存的指针传递给函数free_our_ptr

void free_our_ptr( int **arr,int nrows,int ncols )
                    // ^^ 
{
    int i;
    for(i=0;i<nrows;i++)
    {
        free( arr[i] );
    }
    free( arr );
}

除此之外,您必须像这样分配内存:

arr = malloc( nrows * sizeof(int*) );
                             // ^  type of arr is  int** and type of an element is int*
for(i=0;i<nrows;i++)
{
    arr[i] = malloc( ncols * sizeof(int) );
}

此外,我建议从函数中删除free_our_ptr(&arr,nrows,ncols); numberssquarecubemultiples_of_4multiples_of_5。释放main中的内存,因为您也将其分配在main中。

相关内容

  • 没有找到相关文章

最新更新