2D数组内存分配和传递给函数

时间:2016-01-27 18:03:24

标签: c arrays malloc 2d

我正在编写这个程序,将方形,立方体,4的倍数,5的倍数打印成2维数组。 我总是遇到分段错误错误。你能帮忙解释一下发生了什么吗? 该程序不会打印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("\n\nEnter 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("%d\t",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("%d\t",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("%d\t",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("%d\t",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("%d\t",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("\n\nEnter 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("%d\t",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("%d\t",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("%d\t",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("%d\t",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("%d\t",arr[i][j]);
            number++;
        }
    }

}

2 个答案:

答案 0 :(得分:1)

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

不对。它必须是

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

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

此外,由于您使用的是C而不是C ++,因此请不要使用malloc的返回值。见Do I cast the result of 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 &

答案 1 :(得分:1)

您将指向指针的指针传递给函数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_4中删除multiples_of_5。释放main中的内存,因为您也在main中分配了内存。