1

I am writing this program to print square,cube,multiples of 4, multiples of 5 into a 2 dimensional array. I am always getting a segmentation fault error. Can you please help explain what is going on? The program does not print all the elements of the 2D array. It ends in segmentation fault after 4th or 6th row.

#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);
}

I tried the suggestions, removed free_our_ptr() function altogether and freed the memory in main() itself. On ubuntu linux gcc, it gives a segmentation fault error. However, on Visual Studio-Windows7, runs perfectly fine, no errors in any test cases. Below is the modified code.

#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++;
        }
    }

}
3
  • 2
    Have you ever heard the term three-star programmer? It's not connotated positively, BTW. Take it as a guideline on using pointers. Commented Jan 27, 2016 at 18:09
  • 1
    arr = (int **) malloc ( nrows * sizeof(int)); should be arr = (int **) malloc ( nrows * sizeof(int*)); Commented Jan 27, 2016 at 18:10
  • There is not a single 2D array in your code! There are reasons a pointer id not called "array". Commented Jan 27, 2016 at 20:20

2 Answers 2

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

is not right. It needs to be

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

The first one allocates enough space for nrows of ints.
The second one allocates enough space for nrows of int*s.

Also, since you are using C, not C++, don't cast the return value of malloc. See Do I cast the result of malloc?

Just use:

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

The function free_our_ptr is not right either.

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.
}

My suggestion to fix it is to change the interface to:

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

Then, the code in the function will work. However, you'll need to change all the places it gets used.

Instead of calling it as:

free_our_ptr(&arr,nrows,ncols);

you'll need to call it as:

free_our_ptr(arr,nrows,ncols);
             ^^^ No &
Sign up to request clarification or add additional context in comments.

Comments

1

You pass a pointer to the pointer which refers to the dynminc allocated memory to your function free_our_ptr. Either yo dereference the pointer inside the function:

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***
}

Or you pass the pointer to the dynamic allocated memory to your function 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 );
}

Apart from this you have to allocate your memory like this:

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) );
}

Further I recommend to remove free_our_ptr(&arr,nrows,ncols); from your functions numbers, square, cube, multiples_of_4 and multiples_of_5. Free the memory in main, because you allocataed it in main too.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.