-1

I wanted to know if its possible to declare a 2D array in c even if we dont know the size. I tried doing it like this

char **array;   //2D array of characters - global 
int length, height; // - global

and then in a function declare the size like this

void size_and_data(){
int i;
//some more code here

array=(char**)malloc(sizeof(char*)*height);        //height and length are 
                                                   //given from a file
for(i=0;i<length; i++)
    array[i]= (char*)malloc(sizeof(char)*length);
//more code to follow..
}

Also at this point my array is full of characters and i printed every single one to make sure they are stored correcly. However if i try to access the elements while being in another function im getting a segmentation fault. This is how i try to access them:

void access_f(){
    int i,j;
    for(i=0; i<height;i++){
        for (j=0;j<length; j++)
            printf("%c", array[i][j]);   
    }
}

Keep in mind there aren't any more function involved in between so the array doesn't change in any way. Should this be happening? I thought global variable keep their values untill the programm stops running.
I'm new to c and any help would be greatly appreciated!
Thanks!

  • 2
    Possible duplicate of [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Serge Ballesta Jan 12 '18 at 18:27
  • @user3121023 You are right. The dimensions are mixed up.. – Eugene Sh. Jan 12 '18 at 18:32
  • @EugeneSh. Dimensions are not mixed up. Change to `printf("%c", *(arr+i) + j);` for it to work. – Felix Jan 12 '18 at 18:58
  • 1
    @felix they are mixed up. First allocation if of `height` pointers, but iterating `length` elements. – Eugene Sh. Jan 12 '18 at 19:03
  • @EugeneSh. I stand corrected. It appears the printf won't mind accessing elements outside range if called the way I did. Nor does malloc or the assignation of array[i] throw anything. – Felix Jan 12 '18 at 19:08
  • @felix Seg fault is still there for me plus a warning saying * format '%c' expects argument of type 'int', but argument 2 has type 'char *'*. If i paste the code of accessf() in the size_and_data() function values will be printed normally – Antonis Paragioudakis Jan 12 '18 at 19:13
  • @AntonisParagioudakis Now we're talking! See below for another shot at the solution. – Felix Jan 12 '18 at 19:19

1 Answers1

1

Fix:

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

char **arr;   //2D array of characters - global
int length = 4, height = 3; // - global

void access_f(){
    for(int i = 0; i < height; i++){
        for(int j = 0; j < length; j++){
            *(*(arr+i)+j) = 0; // Set data or whatever
            printf("%d ", *(*(arr+i)+j)); // Should produce an array of zeroes
        }
        printf("\n");
    }
}

int main(){
    arr = (char**)malloc(sizeof(char*) * height);

    for(int i = 0; i < height; i++) // Iterate over correct dimension
    arr[i]= (char*)malloc(length);

    access_f();
    return 0;
}

Background:

The C language does indeed have 2D arrays, but they are stored as a continuous memory block when declared:

int arr[3][2]; // -> int | int | int | int | int | int

They are accessed like this:

arr[2][1]; // Means index 2*cols + 1 = 2*2+1

Manually allocating 2D arrays you will have to allocate two arrays: First the continuous array for the data (it can also be different arrays for each column). Then the array for the pointers to the columns of the data.

int **arr; // arr[3][2]
// Will look like this: int* | int* | int*
// Where each points to data that is capitalized:
// INT | int | INT | int | INT | int
Felix
  • 2,548
  • 19
  • 48