Re: Code fails with Segmentation Fault



Vlad Dogaru wrote:

Hello,

I am trying to learn C, especially pointers. The following code
attempts to count the appearences of each word in a text file, but
fails invariably with Segmentation Fault. Please help me out, I've
already tried all my ideas. Also, please do comment on my coding style
or other aspects. Thank you.

First of all use a debugger to find out where the seg fault occurs.


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

#define INITLEN 5
#define DELTA 5

int main(int argc, char **argv)
{
char **words, *word, *string;
int *apps, max, found, i, n;
FILE *input;

Personally I tend to define each symbol separately; that way I can add a
trailing descriptive comment about the variable.


if (argc != 2) {
printf("Usage: %s <file>\n", argv[0]);
return 0;
}

max = INITLEN;
n = 0;
words = (char **) calloc(max, sizeof (char *));
apps = (int *) calloc(max, sizeof (int));
input = fopen(argv[1], "r");

Now would be a good time to check that all three above lines actually
worked.

Since the size is constant and small I would just declare arrays rather than
allocating memory. However if you are going to adapt it to vary the max
then by all means allocate memory. (Ah. now I see, having looked down the
page)


while (fgets(string, 1000, input)) {

Look up the usage of fgets. string should point to a buffer. You have it
as an uninitialised pointer. That is probably where the seg fault is
occuring

word = strtok(string, " ");
while (word) {
found = 0;
for (i=0; i<n; i++)
if (!strcmp(words[i], word)) {

Many people use that form as a shorthand for == 0. In the case of strcmp I
probably would explicitly put strcmp() == 0 (although I vacilate); ! gives
an indication of negativeness whereas it is actually a positive thing that
the word matches. However that is being really picky

found = 1;
apps[i]++;
break;
}
if (!found) {

Now here I agree with using !

words[n] = strdup(word);

Did it succeed?

apps[n] = (int) malloc(sizeof(int));

Did it succeed?

apps[n] = 1;
n++;
if (n == max) {

I would probably do the expansion earlier; expand if we need the extra room
You are expanding assuming that you WILL need the room in a moment.

max += DELTA;
words = (char **) realloc(words, max);
apps = (int *) realloc(apps, max);

Did they succeed?

}
}
word = strtok(NULL, " ");
}
}

for (i=0; i<n; i++)
printf("Word '%s' appears %d time(s).\n", words[i], apps[i]);

return 0;
}

And then all you have to worry about is words split over lines and lines
that don't fit in the string buffer.

--
Bill Medland
.



Relevant Pages

  • Re: A taxonomy of types
    ... I am describing how to represent the representation (and, ... if the system follows static typing rules (such as in a compiler), ... so, the hardware sees pointers and pointer arithmetic, but the compiler ... "Besides the char types, up to three sizes of integer, declared short int, ...
    (comp.lang.misc)
  • Re: Malloc code
    ... int xxx; ... As for not using the void pointer, I will have to do some further testing ... I just needed some insight on passing arrays of pointers. ... struct MCB *r1; ...
    (microsoft.public.vc.language)
  • I want my segmentation fault!
    ... no occurrences of free and a lot of routines returning pointers to ... the pointer returned by the allocator (either directly or as a component ... int length_of_list; ...
    (comp.lang.c.moderated)
  • Re: Simple question, err... I think
    ... Your nodes contain no other indication of which pointers are valid, ... struct CountedObject ... int is_red; ... bool lament(char const s) ...
    (comp.programming)
  • Re: what is wrong with this code ? hi-q
    ... When run it gives me seg fault in linux. ... > int i, j; ... These are all valid ranges for the array a so no seg fault here. ... as one double for loop or something that initialized the first bit as ...
    (comp.lang.c)