Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Passing an array of strings as argument and modifying it dynamically within the function in C

I need to dynamically populate an array of strings in C. Here is the example of my code. Compiles fine, segmentation faults. Is it possible to achieve this functionality?

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

#define MAX_FILE_NAME_LENGTH 255

void loadList(char*** files,int *filesSize);

int main (int argc, char *argv[])
{
  char** files;
  int filesSize=-1;

  loadList(&files, &filesSize);
  //printf("filesize= %d\n",filesSize );
  for(int i=0;i< filesSize;i++) printf("%s\n", files[i]);
  free(files);

  return 0;
}

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

void loadList(char*** files,int *filesSize){
 *filesSize=3;
 //some arry for the example
 char *values[] = {"100.dat", "150.dat", "200.dat"};
 for(int i=0;i< *filesSize;i++){
   *files=(char**) realloc(*files,(i+1) * sizeof(**files));
   *files[i]=malloc((MAX_FILE_NAME_LENGTH+1) * sizeof(char*));
   strcpy(*files[i],values[i]);
   printf("%s\n", files[i]);
 }
}


>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

In *files = (char **)realloc(*files, (i + 1) * sizeof(**files)); you rely on *files to point at already allocated memory or NULL. Neither is true.

*files[i] should also be (*files)[i] because of operator precedence.

You also forgot to free the allocations made inside the loop. A fix could look like this:

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

#define MAX_FILE_NAME_LENGTH 255

void loadList(char ***files, size_t *filesSize) {
    // some array for the example
    const char *values[] = {"100.dat", "150.dat", "200.dat"};
    *filesSize = sizeof values / sizeof *values;

    *files = NULL; // crucial for first realloc

    for (int i = 0; i < *filesSize; i++) {
        *files = realloc(*files, (i+1) * sizeof **files);
        // I'm using strlen here instead of MAX_FILE_NAME_LENGTH but
        // you can change that back if you want more space than the
        // strings really need.
        (*files)[i] = malloc((strlen(values[i]) + 1) * sizeof(char));
        strcpy((*files)[i], values[i]);
    }
}

int main(int argc, char *argv[]) {
    char **files;
    size_t filesSize = -1;

    loadList(&files, &filesSize);
    // printf("filesize= %d\n",filesSize );
    for (int i = 0; i < filesSize; i++) printf("%s\n", files[i]);

    // free what was allocated in the loop
    for (int i = 0; i < filesSize; i++) free(files[i]);
    free(files);

    return 0;
}

One note on files = realloc(*files, ... though:
If realloc fails you’ve lost the original pointer and will not be able to recover. Either assign the return value to a temporary variable and check that it worked or return from the function (after setting *filesSize to i) or exit the program if *files == NULL.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading