Question

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void sortString(const char* input, char* output);
int cmpstr(void const *a,void const *b);
int readAllWords(FILE* f, char*** res, int * num_read);
int main (int argc, char ** argv)
{
   char **wordList;
   FILE* fid;
   int numWords;
   fid = fopen(argv[1],"r");
  readAllWords(fid, &wordList,&numWords);
}

int readAllWords(FILE* f, char*** res, int * num_read)
{
    char buffer[128];
    *num_read = 0;
    int size;
    while(fgets(buffer,128,f))
    {
       *num_read = *num_read +1;
       size = strlen(buffer);
       res = (char***)malloc(sizeof(char**));
       *res = (char **)realloc(*res,sizeof(char*)*(*num_read));
       (*res)[(*num_read)-1] = (char *)realloc((*res)[(*num_read)-1],sizeof(char)*size);
        strcpy((*res)[(*num_read)-1],buffer);
      printf("%s\n",(*res)[(*num_read)-1]);
    }
    printf("%s\n",(*res)[0]);

}

The values are storing and it prints out inside the while loop. But after the while loop, it cannot print out the strings.

The File is given in the main function. Do not understand why realloc is causing the loss of data?

Était-ce utile?

La solution

One problem is that the code doesn't initialize res in main(), so you attempt to realloc() an indeterminate value. Either NULL or a value previously returned by malloc() or realloc() (or calloc()) would be OK, but since you pass an indeterminate value, you are invoking undefined behaviour, and a crash is a valid response to doing that.

However, there's a lot of other code in the function that should be reviewed as well.

This code works, and gets a clean bill of health from valgrind.

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

void readAllLines(FILE *f, char ***res, int *num_read);

int main(int argc, char **argv)
{
    char **wordList = 0;
    FILE *fid;
    int numLines = 0;
    if (argc > 1 && (fid = fopen(argv[1], "r")) != 0)
    {
        readAllLines(fid, &wordList, &numLines);
        fclose(fid);
        for (int i = 0; i < numLines; i++)
            printf("%d: %s", i, wordList[i]);
        for (int i = 0; i < numLines; i++)
            free(wordList[i]);
        free(wordList);
    }
    return 0;
}

void readAllLines(FILE *f, char ***res, int *num_read)
{
    char buffer[128];
    int size;
    while (fgets(buffer, sizeof(buffer), f))
    {
        *num_read = *num_read + 1;
        size = strlen(buffer) + 1;
        char **space = (char **)realloc(*res, sizeof(char *) * (*num_read));
        if (space == 0)
            return;
        *res = space;
        (*res)[*num_read - 1] = (char *)malloc(sizeof(char) * size);
        if ((*res)[*num_read - 1] == 0)
            return;
        strcpy((*res)[*num_read - 1], buffer);
        printf("%s\n", (*res)[*num_read - 1]);
    }
    printf("%s\n", (*res)[0]);
}

Autres conseils

Possible reason for a segmentation fault:

 res = (char***)malloc(sizeof(char**));
 *res = (char **)realloc(*res,sizeof(char*)*(*num_read));

In the second line you try to reallocate whatever *res is pointing to. However since you did not initialize *res this could be anything. This will work only if *res == NULL. I guess it should be malloc, not realloc.

Other problems:

You allocate everything new in each loop iteration. This is a huge memory leak.

You already pass a valid memory address pointing to an char** by res, you shouldn't allocate for it again. It is an out parameter. (Remove the malloc call)

You need an initial malloc for *res before the loop (Or set *res = NULL).

The second realloc for *res[...] should be a malloc, because you never actually reallocate here. Also instead of allocating size bytes, you should allocate size+1 bytes for the terminating \0.

Your function has no return statement although it is non-void.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top