0

I have a function I would like to have a function to receive a 2D array (H), to read a specified column (col) and to pass it to another array (b). It appears that the code below is not OK has I was expecting to get a 1 printed. Any guidance is very much appreciated.

#define nline 5
#define ncol 4

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

void count0(int **M,int col, int *a);

void main(){

    int i;     
    int **H;

    H=(int**)malloc(nline*sizeof(int*));
    for(i=0;i<nline;i++){
        H[i]=(int*)malloc(ncol*sizeof(int));
    }

    H[0][0]=8;
    H[0][1]=5;
    H[0][2]=6;
    H[0][3]=0;
    H[1][0]=7;
    H[1][1]=5;
    H[1][2]=4;
    H[1][3]=0;
    H[2][0]=5;
    H[2][1]=1;
    H[2][2]=1;
    H[2][3]=7;
    H[3][0]=0;
    H[3][1]=0;
    H[3][2]=0;
    H[3][3]=2;
    H[4][0]=1;
    H[4][1]=0;
    H[4][2]=1;
    H[4][3]=4;

    int *b;

    int col=1;

    count0(H,col,&b); 

    printf("num 0=%d\n",b[2]); getchar();

}

/////////////////////////////////////////////////////////////////////////////////

void count0(int **M,int col, int *a){

    int i;

    a=(int*)malloc(1*sizeof(int));

    for(i=0;i<nline;i++){
        a[i]=M[i][col];
        a=realloc(a,(i+2)*sizeof(int));
    }
}
Shahbaz
  • 46,337
  • 19
  • 116
  • 182
user16720
  • 1
  • 1
  • Side note: do `type *var = malloc(size * sizeof(*var));` it's less verbose, and you don't repeat the `type` three times. – Shahbaz Jul 30 '13 at 16:35
  • `void count0(int **M,int col, int *a){` should be `void count0(int **M,int col, int **a){` – BLUEPIXY Jul 30 '13 at 16:38
  • In C, you don't cast from `void *` to other pointer types. –  Jul 30 '13 at 16:40

3 Answers3

2

Your argument for the output b is wrong. It needs to be a pointer to a pointer (like how you pass it). Right now you should get a compiler warning about it. The function prototype should be

void count0(int **M,int col, int **a);

Then in the function you need to use the dereference operator to access a:

*a = malloc(1*sizeof(int));

Note that I don't cast the return value of malloc, there no need to and neither should you.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thks! And if instead of a be an 1D array it was a 2D array? A triple pointer would needed to be defined in the function arguments int*** a? – user16720 Jul 31 '13 at 08:48
  • @user16720 It all depends on how you declare the variable you pass into the function, but if you do it like `H` (the `M` argument in `count0`) then yes. – Some programmer dude Jul 31 '13 at 08:58
1

As you already knows the number of rows = nline in your matrix in count0 function. So you should simply allocate all memory for array a in count function one time, you don't need to re-call realloc() function.

void count0(int **M, int col, int** a){
   (*a) = malloc(nline * sizeof(int));
   for(i = 0; i < nline; i++){ 
      (*a)[i] = M[i][col];
   }
}

Note: precedence of [] is higher then * so you need () around *a

just call this function as: count0(H, col, &b);

and free(b); in main() after printf statement to deallocate memory explicitly.

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • Thks! And if instead of a be an 1D array it was a 2D array? A triple pointer would needed to be defined in the function arguments int*** a? – user16720 Jul 31 '13 at 08:47
  • @user16720 yes! and Check this answer: [Allocate memory 2d array in function C](http://stackoverflow.com/questions/15062718/allocate-memory-2d-array-in-function-c?answertab=votes#tab-top) – Grijesh Chauhan Jul 31 '13 at 08:51
  • @user16720 if you wants to [allocate memory for 3d](http://stackoverflow.com/questions/17761205/dynamic-pointing-array-to-a-dynamic-2-dimensions-array/17761224#17761224) – Grijesh Chauhan Jul 31 '13 at 08:52
0

You are trying to have this variable:

int * b;

Point to an newly allocated array after this call:

count0(H,col,&b); 

To do this, you must change the signature of count 0 to the following:

void count0(int **M,int col, int **a);

Note that int *a is now int **a. Then in the body of count0, you must use the following lines to allocate/reallocate a:

*a=(int*)malloc(1*sizeof(int));
*a=realloc(a,(i+2)*sizeof(int));

Right now, a is a pointer variable that only exists in the scope of count0. Initially its value is &b (which right now doesn't make sense since &b is an int**, and a is an int*). You have a point to newly allocated memory, which is lost after the function. The changes I suggest will have *a, and therefore b, to point to memory that can be retrieved after the function call.

fatsmcgee
  • 314
  • 1
  • 4
  • Thks! And if instead of a be an 1D array it was a 2D array? A triple pointer would needed to be defined in the function arguments int*** a? – user16720 Jul 31 '13 at 08:48
  • It depends what you want to do! If you want to allocate space for the "rows" of this 2D array, as you do earlier with `H=(int**)malloc(nline*sizeof(int*));`, then yes. You would pass `int *** a`, and call `&a = (int**)malloc(nline*sizeof(int*));`. Assuming you have already done this, and you want to allocate "columns", as you do earlier in the program with `H[i]=(int*)malloc(ncol*sizeof(int));`, you would be able to still pass `int ** a` and simply call `a[i] = (int*)malloc(ncol*sizeof(int));` . That is because `a[i]` will already reference space for a int pointer. – fatsmcgee Jul 31 '13 at 21:43