-2

I can't figure out what is wrong with this chunk of code (and couldn't find any advice from previous Q&A):

#include<stdio.h>

void fld(const int **b){
int i, j ;
printf("Hello R\n");
for (i=0; i<3; i++){
    for (j = 0; j<3; j++)
        printf("%d", b[i][j]);
    printf("\n");
    }
return;
}

int main(){
int i, j;
int b[3][3] = {
            {1,1,1},
            {1,2,1},
            {2,2,2}
            };

fld((void **)b);
system("pause");
return;
}

I tried to pass a matrix to a function fld and to print it out, but it keeps reporting segmentation fault while running the code.

brnady
  • 29
  • 4

2 Answers2

2

Here is a version that allocates memory dynamically on the heap. It works like the main() argument *argv[] namely an array of arrays (although in that case the row lengths might be different). In this answer, you don't need to pass the array sizes for fld() to work: but to tell it when to stop! The reason is, it's a 1-D array of array pointers, each of which is also a 1-D array. You can extend the same approach to a 3-D array too.

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

int **intarray(int rows, int cols) {
    int r;
    int **arr = malloc(rows*sizeof(int*));   // here an array of pointers
    if (arr == NULL)
         return NULL;
    for (r=0; r<rows; r++) {
        arr[r] = malloc(cols*sizeof(int));   // here an array of ints
        if (arr[r] == NULL)
             return NULL;
    }
    return arr;
}

void fld(const int **b, int rows, int cols){
    int i, j ;
    printf("Hello R\n");
    for (i=0; i<rows; i++){
        for (j = 0; j<cols; j++)
            printf("%-5d", b[i][j]);
        printf("\n");
        }
return;
}

int main(void) {
    int i, j;
    int **b = intarray(3, 3);
    if (b == NULL)
        return 0;
    for (i=0; i<3; i++)
        for (j=0; j<3; j++)
            b[i][j] = i*100 +j;
    fld(b, 3, 3);

    // free() the memory
    return 0;
}

Program output

Hello R
0    1    2
100  101  102
200  201  202
Weather Vane
  • 33,872
  • 7
  • 36
  • 56
0
void fld(const int b[][3]){
    int i, j;
    printf("Hello R\n");
    for (i=0; i<3; i++){
       for (j = 0; j<3; j++)
           printf("%d", b[i][j]);
       printf("\n");
    }
return;
}

int main(int argc, char** argv) {

int b[3][3] = {
        {1,1,1},
        {1,2,1},
        {2,2,2}
        };

fld(b);
return 0;
};

Compiles and runs with g++

Ivo Peterka
  • 125
  • 1
  • 7
  • why don't you define the boundary in the first bracket []? – brnady Mar 03 '15 at 20:29
  • 1
    It could be. The problem of passing a 2-d array is that `fld()` does not know whether it is a 2*4 or 3*3 or 4*2 array. This answer shows how to deal with that - the compiler needs to know how many elements are in each row of the array. Then, as ever in C, it's up to the user to use a row index that is within bounds. – Weather Vane Mar 03 '15 at 20:35
  • thanks, i get it: so in arrays you have a compacted memory space which needs to be divided into chunks of data of known size. casting an array as a pointer of int ** type does help a bit, but it doesnt convey information on how are those integers divided into rows what is really important when trying to reach some element. That is as well why the code compiles in 1D, whereas not in 2D. – brnady Mar 03 '15 at 20:42
  • as well, when some data is stored in a array of pointers allocated space (pointers to pointers style) you do not need declared boundaries as it is allways clear that b[2][3] means check the 2nd pointer in the "row"(acctually 1d array),(in the array scheme the question is where the 2nd row starts... as its all compacted and of same type) then use that pointer to go to another memory address and then pick the third chunk of integer sized data... (as well it doesn't care if it has or hasn't overread some data). – brnady Mar 03 '15 at 21:02
  • in other words : if you have an array style data collection b[x][y] means go to b+x*columnsize*intsize+y*intsize location (so colsize is important), in pointer styled formation, it means check adress at b+ptrsize*x , go there and check the typesize*y data. – brnady Mar 03 '15 at 21:06
  • if youre not sure about your matrix size or youre sure its going to change.. you should either take the pointer styled formation and think of it as a interconnected map, or take a matrix large enough to accomodate all your needs, adding some way to mark the unused space for further notice. If there is no such need, for better usage of memory space, you should stick to the compact matrix formation, unless you need a big matrix. Then you will have to use heap part of memory where you are obliged to use pointer styled syntax (inc. malloc(), alloc() and free()). – brnady Mar 03 '15 at 21:11