views:

103

answers:

3

I am trying to allocate a array of char*'s in C. I know the number of columns in advance, but not the rows and I want to allocate the rows as and when needed.

I tried to use:

char *(*data)[NUMCOLS]; //declare data as pointer to array NUMCOLS of pointer to char

data = malloc(sizeof(char*));

now, the above line should allocate for data[0] ... correct? then, I must be able to use the row like

data[0][1] = strdup("test");
 .
 ..
data[0][NUMCOLS-1] = strdup("temp");

I am getting seg fault. I am not able to understand what is wrong here. can anyone please help.

A: 

It should be like this .

char **data = NULL;

data = NUMCOLS*malloc(sizeof(char*));

and now you do what you wanted

data[0][1] = strdup("test"); . .. data[0][NUMCOLS-1] = strdup("temp");

Night Walker
There are some mistakes in your answer. 1. don't multiply the address of the allocated memory by NUMCOLS, but the sizeof(char *). 2. You have to chose if you want a 1d or a 2d array. data[0][1] is a single character and not an string address.
quinmars
The variable declaration is incorrect, and the other two lines won't even compile.
John Kugelman
+2  A: 

You haven't allocated enough memory for the things that you want to store. In this particular case, that would be:

data=malloc(sizeof(char*)*NUMCOLS*NUMROWS);

To resize the array, you would use:

data=realloc(data,(size_t)sizeof(char*)*NUMCOLS*NEW_NUMROWS);

More about it (reallocation) here

Aviral Dasgupta
`data = malloc(NUMROWS * sizeof *data);` is another option.
caf
@caf First of all, you're gonna get an error, since you haven't specified a data type for sizeof. Secondly, when I said NUMCOLS, it was synonymous with the length of that particular string. Secondly : in context of the OP's question, "data" is a pointer so if data were already allocated and your code compiled, then it would run out of memory to allocate.
Aviral Dasgupta
This approach is with char ***data? or char *(*data)[]
vyom
It's for a char***. Ps. Please don't mutuate types by putting parens. If you add one more, it'll become a function pointer...
Aviral Dasgupta
A: 

I would do this:

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

int main(){
  char ***a = NULL;

  a       = realloc( a, 1 * sizeof(char **) ); // resizing the array to contains one raw
  a[0]    = malloc(     3 * sizeof(char  *) ); // the new raw will contains 3 element
  a[0][0] = strdup("a[0][0]");
  a[0][1] = strdup("a[0][1]");
  a[0][2] = strdup("a[0][2]");


  a       = realloc( a, 2 * sizeof(char **) ); // resizing the array to contains two raw
  a[1]    = malloc(     3 * sizeof(char  *) ); // the new raw will contains 3 element
  a[1][0] = strdup("a[1][0]");
  a[1][1] = strdup("a[1][1]");
  a[1][2] = strdup("a[1][2]");

  for( int rows=0; rows<2; rows++ ){
    for( int cols=0; cols<3; cols++ ){
      printf( "a[%i][%i]: '%s'\n", rows, cols, a[rows][cols] );
    }
  }
}
sambowry