Click here to Skip to main content
15,868,419 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello guys...
I use C to do a 2d array without total success.I get the below error:
Segmentation fault (core dumped)


Explaining the code:

First I give rows and cols via input and then I print the 2d_array with random numbers between 1 to 100.
When print_2d_array(.....) is going to run I receive the above error.

Code:

What I have tried:

C++
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int rows_col(char *str);
int randomness();
void print_2d_array(int **array , int rows , int cols);

int main(void)
{
    srand(time(NULL));
    int **array_2d;
    int rows = rows_col("rows");
    int cols = rows_col("columns");
    array_2d = malloc(sizeof(int) * rows * cols);
    print_2d_array(array_2d , rows , cols);
    printf("\n\n\n");
    free(array_2d);
}


int rows_col(char str[10])
{
    int num = 1;
    printf("Give the number of %s: " , str);
    do
    {
        if(num <= 0)
        {
            printf("This is a negative/zero number.Please try again.\n");
            printf("Give the number of %s: " , str);
        }
        scanf("%d" , &num);
    }
    while(num <= 0);
    return num;
}


int randomness()
{
    return ( (rand() % 100) + 1);
}



void print_2d_array(int **array , int rows , int cols)
{    
    for(int i = 0; i < cols; i++)
    {
        for(int j = 0; j < rows; j++)
        {
            array[i][j] = randomness();
            printf("%d\t" , array[i][j]);
        }
        printf("\n");
    }
}



I want your help to find/solve this problem.
Thanks in advance!!!
Posted
Updated 25-Aug-20 21:45pm
Comments
jeron1 25-Aug-20 16:06pm    
One thing,

Hide   Copy Code
    while(num <= 0);


Once this loop starts, it won't stop (endless loop).


:edit: complete brainfart.
OriginalGriff 25-Aug-20 16:25pm    
No, it's the end of a do { ... } while (num <=0);
jeron1 25-Aug-20 16:38pm    
Indeed, hopefully that's the dumbest thing I say today, trying to re-engage brain...
Nick_is_asking 25-Aug-20 16:22pm    
I disagree ,because when comes through do statement ,scanf is called so it waits for user and then check the number.This is how do while works
I checked it and it works as I expected.
jeron1 25-Aug-20 16:36pm    
Doh! You're absolutely right, my apologies! apparently my caffeine buzz has worn off.

You have the declaration:
C
int **array_2d;
This declares array_2d as a pointer to pointer to int. But then you allocate the array with
C
array_2d = malloc(sizeof(int) * rows * cols)
. The malloc() returns a contiguous block of memory (i.e. int *, which is not a pointer to pointer to int
You have 2 choices:
1) allocate an array of int * that is rows long, then allocate an array of int that is cols long for each row
C
int **array_2d;
array_2d = malloc(sizeof(int*) * rows); // This creates an array of pointers to int
for(int i = 0; i < rows; ++i) {
    array_2d[i] = malloc(sizeof(int) * cols); // This creates a row of ints and asigns it to array_2d[i]
}


2) Since you are using ubuntu and GCC you can make use of gnu extensions and dynamically size the array in print_2d_array()
C
void print_2d_array(void *ptr, int rows, int cols)
{
    int (*array)[rows] = ptr;  /* dynamically size array based on rows !! */
    for(int = 0; i < cols; ++i)
    {
        /* your code  here as before */
    }
}

In this case you don't need to change your allocation of array_2d in main()
 
Share this answer
 
As far as I remember,
C++
int **array_2d;

you declare a pointer to a list of pointers to lists of integers.
But here,
C++
array_2d = malloc(sizeof(int) * rows * cols);

malloc makes a list of integers and return a pointer to the list, and the pointer returned by malloc have no knowledge that you want a 2d array.
You mismatched array type and memory allocation.

C++
//A chunk of memory is basically 1D
0 1 2 3 4 5 6 7 8
// but with a little logic, it is 2D
0 1 2 // row 0
3 4 5 // row 1
6 7 8 // row 2
// the logic to convert 2D to 1D is
position= row * cols + col;
 
Share this answer
 
v3
What you need to do is look at what is happening while your code is running.
Fortunately, you have a tool available to you which will help you find out what is going on: the debugger. How you use it depends on your compiler system, but a quick Google for the name of your IDE and "debugger" should give you the info you need.

Put a breakpoint on the first line in the function, and run your code through the debugger. Then look at your code, and at your data and work out what should happen manually. Then single step each line checking that what you expected to happen is exactly what did. When it isn't, that's when you have a problem, and you can back-track (or run it again and look more closely) to find out why.

Sorry, but we can't do that for you - time for you to learn a new (and very, very useful) skill: debugging!
 
Share this answer
 
Other solutions have given you about everything you need with one exception and that is how to release this memory. You must always remember to release the memory that you allocate. Here are pair of functions to handle allocation and release of a 2D array of any type.
C
// release function for the 2D array allocator

void **Free2DArray( void **array, int xdim )  // xdim is the number of rows
{
    int x;

    if( array == NULL )
        return NULL;        // sanity check

    // release each row in reverse order of allocation
 
    for( x = xdim - 1; x >= 0; x-- )
    {
        if( array[ x ] )
        {
            free( array[ x ] );
            array[ x ] = NULL;
        }
    }

    // release the pointer to the row pointers

    free( array );
    return NULL;
}

// a general 2D array allocator - array is accessed as : array[ x ][ y ]
// example : int ** array = Alloc2DArray( rows, sizeof( int * ), cols, sizeof( int ) );
// a macro to help :
#define Allocate2D( r, c, t ) Alloc2DArray( r, sizeof( t * ), c, sizeof( t ) )
// example : int ** array = Allocate2D( rows, columns, int );

void ** Alloc2DArray( int xdim, int xitmsize, int ydim, int yitmsize )
{
    int     i;
    int     x;
    void ** data;

    // allocate a pointer to the pointers to each row of data

    data = (void **)calloc( xdim, xitmsize );
    if( data == NULL )
        return NULL;

    // now allocate each row

    for( x = 0; x < xdim; x++ )
    {
        data[x] = calloc( ydim, yitmsize );
        if( data[x] == NULL )
        {
            Free2DArray( data, xdim );  // release what we got
            return NULL;                // and bail out
        }
    }

    return data;
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900