3

How to create an array of strings when there isn't a fixed length of items or characters. I'm new to pointers and c in general and I couldn't understand the other solutions posted on here so my solution is posted below. Hopefully it helps someone else out.

Cadell Christo
  • 3,105
  • 3
  • 21
  • 19
  • Are you looking for a jagged array (array of arrays of different length), or X*Y fixed size array? And are you looking for 2-dimensional array of strings(==pointers to char), or are you looking for array of pointers to arrays of strings(==pointers to char), or are you looking for 3-dimensional array of char with no pointers in the array? – hyde Oct 28 '12 at 13:11
  • i was looking for a way to store strings in an array and access them like string1 = array[1] etc when i didn't know the number of strings nor their length. is that pointers to character pointers? – Cadell Christo Oct 28 '12 at 13:15
  • Ok, so you are actually looking for a single array of strings (=char pointers). Thinking of it as a 2D array is probably not helpful (even if it is true from a certain point of view). – hyde Oct 28 '12 at 13:22
  • The OP's wanting a *1d*-array of pointers to character. So it might be a good idea to adjust the title of the question accordingly. – alk Oct 28 '12 at 15:26

3 Answers3

2
char **twod_array = NULL;

void allocate_2darray(char ***source, int number_of_slots, int length_of_each_slot)
{
   int i = 0;
   source = malloc(sizeof(char *) * number_of_slots);
   if(source == NULL) { perror("Memory full!"); exit(EXIT_FAILURE);}
   for(i = 0; i < no_of_slots; i++){
      source[i] = malloc(sizeof(char) * length_of_each_slot);
      if(source[i] == NULL) { perror("Memory full!"); exit(EXIT_FAILURE);}
   }
} 

// sample program

int main(void) { 
   allocate_2darray(&twod_array, 10, 250); /*allocate 10 arrays of 250 characters each*/ 
   return 0;
}
Aniket Inge
  • 25,375
  • 5
  • 50
  • 78
  • Your `source` pointer will be lost when the `allocate_2darray` function returns. You should change the argument type to `char***` and pass it as `&twod_array`. Also, since you are allocating uniformly sized arrays, this solution wouldn't be very good if the lengths of each string can vary widely. – Geoff Montee Oct 28 '12 at 13:28
  • you have realloc for varying lengths. I don't understand the source pointer being lost, you're passing in the pointer. – Aniket Inge Oct 28 '12 at 16:41
  • 1
    yes, you are passing in the pointer by value. The original pointer is not being modified. `twod_array` will be `NULL` after the function is returned. You need to pass a pointer to the pointer itself, hence `char***`. I know, it is confusing. – Geoff Montee Oct 28 '12 at 17:03
  • see the code that I posted in my answer. That is the kind of thing that I am talking about. – Geoff Montee Oct 28 '12 at 17:09
1

Simply makes an array from the argv items bar the first item.

char **dirs = NULL;
int count = 0;
for(int i=1; i<argc; i++)
{
    int arraySize = (count+1)*sizeof(char*);
    dirs = realloc(dirs,arraySize);
    if(dirs==NULL){
        fprintf(stderr,"Realloc unsuccessful");
        exit(EXIT_FAILURE);
    }
    int stringSize = strlen(argv[i])+1;
    dirs[count] = malloc(stringSize);
    if(dirs[count]==NULL){
        fprintf(stderr,"Malloc unsuccessful");
        exit(EXIT_FAILURE);
    }
    strcpy(dirs[count], argv[i]);
    count++;
}
Cadell Christo
  • 3,105
  • 3
  • 21
  • 19
  • You should change `int arraySize = (count+1)*sizeof(dirs);` to `int arraySize = (count+1)*sizeof(char*);`. Semantically, your code is a bit incorrect, since `dirs` is a `char**` but you are allocating `char*`. In practical terms, it shouldn't make a difference either way, since `sizeof(char**) == sizeof(char*)`. – Geoff Montee Oct 28 '12 at 13:16
  • you're right i've edited it in it makes more sense that way because dirs is an array of pointers – Cadell Christo Oct 28 '12 at 13:19
1

Yours is close, but you are allocating the main array too many times.

char **dirs = NULL;
int count = 0;

dirs = malloc(sizeof(char*) * (argc - 1));

if(dirs==NULL){
    fprintf(stderr,"Char* malloc unsuccessful");
    exit(EXIT_FAILURE);
}

for(int i=1; i<argc; i++)
{
    int stringSize = strlen(argv[i])+1;
    dirs[count] = malloc(stringSize);
    if(dirs[count]==NULL){
        fprintf(stderr,"Char malloc unsuccessful");
        exit(EXIT_FAILURE);
    }
    strcpy(dirs[count], argv[i]);
    count++;
}
Geoff Montee
  • 2,587
  • 13
  • 14
  • yes this would be more appropriate for the argv case i was really just using argv as an example to show how to do it if we didn't know argc – Cadell Christo Oct 28 '12 at 13:09