0

I need to solve this exercise this way because the given function needs to have these parameters, the problem is I'm getting core dumped at around the 20th string I read:

int load(char *filename, char ***words) {
    char **pt = (*words);
    *words = (char **)malloc(sizeof(char*));
    char s[50];

    FILE *f = fopen(filename, "r");
    int i = 0, t;

    while (fscanf(f, "%s", s) == 1) {
        t = strlen(s);
        printf("%d    ", t);
        s[t] = '\0';

        pt = (char **)realloc(pt, sizeof(char*) * (i + 1));
        pt[i] = (char *)realloc(pt[i], sizeof(char) * (t + 1));

        strncpy(pt[i], s, t + 1);
        printf("%s\n", pt[i]);

        i++;
    }
    return 0;
}

I'm using pt as a char** just to test how this works, the objective is to store in the ***words the strings in the textfile:

textfile:

break
int
case
long
char
continue
return
default
short
do
sizeof
double
static
else
struct
switch
typedef
float
for
unsigned 
goto
while
chqrlie
  • 131,814
  • 10
  • 121
  • 189
João Gomes
  • 81
  • 10
  • 1
    `t = strlen(s) --> s[t] - '\0'` of `strlen()` worked then `s[t]` is already `'\0'`. Did you know that `malloc()` is not infallible? – Iharob Al Asimi Jan 18 '16 at 18:42
  • I don't really know what the main problems with malloc can be, I learned how to use it in a very basic way last week in class... – João Gomes Jan 18 '16 at 18:44
  • 2
    dont cast return of malloc, see here: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – ForeverStudent Jan 18 '16 at 18:46
  • @JoãoGomes Always check that `malloc()` did not return `NULL`. – Iharob Al Asimi Jan 18 '16 at 18:49
  • First the code stores to `pt` where `words` points to then it overwrites this very value in `*words` but continues to use `pt`. Does this make sense? ;) – alk Jan 18 '16 at 19:17

2 Answers2

2

I assume you want to use this as a return parameter?

char **pt=(*palavras);

Here, you get the current value.

pt=(char **) realloc(pt,sizeof(char*)*(i+1));

now you overwrite that value with a maybe-new allocation.

you probably are missing a

*palavras = pt;

to return this value? Otherwise, you are likely leaking the memory allocated.

Furthermore, you have an incorrect realloc here:

pt[i] = (char *)realloc(pt[i], sizeof(char) * (t + 1));

Because the old value of pt[i] is undefined (if you are lucky, your kernel or libc initialized this as NULL, although you did not request memory initialization.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
  • My problem right now is not returning, is the fact that I can't read all the textfile because I get a core dump before it :S – João Gomes Jan 18 '16 at 18:48
  • Learn the difference between `realloc`, `alloc` and `calloc`. Then fix your allocation code. Avoid overusing realloc, but mostly use it to *shrink* an overly large allocation to its ginal size. – Has QUIT--Anony-Mousse Jan 18 '16 at 21:47
1

The array pointer pt should be initialized to NULL and the final value stored to *words just before returning from the function.

Furthermore, you do not set pt[i] to NULL when you reallocate pt here:

pt = (char **)realloc(pt, sizeof(char*) * (i + 1));

The reallocated space beyond the previous size is not initialized. Fix the code this way:

pt = realloc(pt, sizeof(char*) * (i + 1));
pt[i] = NULL;

You can actually simplify the code by using strdup to allocate the strings:

int load(char *filename, char ***words) {
    char **pt = NULL;
    char s[50];
    int i = 0, t;

    FILE *f = fopen(filename, "r");
    if (f != NULL) {
        for (; fscanf(f, "%49s", s) == 1; i++) {
            t = strlen(s);
            printf("%d    ", t);
            pt = realloc(pt, sizeof(*pt) * (i + 1));
            pt[i] = strdup(s);
            printf("%s\n", pt[i]);
        }
    }
    *words = pt;
    return i;
}

I made the function return the number of words loaded into the words array, otherwise, there would be no way to know.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • I tought realloc initialized automatically – João Gomes Jan 18 '16 at 19:05
  • @JoãoGomes: no it does not, it preserves the contents of the part that was reallocated to a larger size even if it moves, but the newly allocated bytes at the end are uninitialized, so they can have any random contents. calling `realloc(pt[i], t + 1)` invokes undefined behavior. – chqrlie Jan 18 '16 at 19:37