PDA

View Full Version : pulling my hair out


EscapeCharacter
12-21-2002, 12:43 PM
ive been trying one of the contests someone in #coderforums showed me and ive run into a wall and i am going crazy trying to figure out whats wrong because it doesnt look like like anything is wrong. ive got this linked list function that adds elements to the list but for some reason the list always ends up being null so the null part of my add function is always executing instead of the the not null part, well anyways more eyes are better(its probably something stupid) so heres the code

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

struct word{
char *w;
unsigned int count;
struct word *next;
};

typedef struct word word;

word *newWord(char *chr, word *list){
word *new, *tmp;
tmp = list;
new = (word*)malloc(sizeof(word));
if(list == NULL){
//part that should be working but isnt
list = new;
list->w = (char*)malloc(sizeof(char)*strlen(chr));
list->w = chr;
list->count = 1;
list->next = NULL;
printf("first %s\n", list->w);
}
else{
while(tmp->next != NULL)
tmp = tmp->next;
tmp->next = new;
new->w = (char*)malloc(sizeof(char)*strlen(chr));
new->w = chr;
new->count = 1;
new->next = NULL;
printf("yo\n");
}
}


word *wordCount(FILE *fp){
int c;
int x;
word *list;
char wrd[255];
x = 0;
list = NULL;
printf("this is list before loop %d\n", list);
while((c = fgetc(fp)) != EOF){
wrd[x] = (char)c;
if(wrd[x] == ' '){
wrd[x] = '\0';
newWord(wrd, list);
x = 0;
}
else{
x++;
}
}
printf("this is list in wordCount %d\n", list);
return list;
}

unsigned words(FILE *fp){
unsigned int count;
int chr;
count = 0;
//chr = (char*)malloc(sizeof(char));
while((chr = fgetc(fp)) != EOF){
if(chr == ' ' || chr == '\t' || chr == ','){
count++;
}
}
printf("\n########## Word count complete ##########\n");
return count;
}

int main(int argc, char **argv){
FILE *ptr;
unsigned int count;
word *root, *tmp;
//const char *p;
count = 0;
if(argc != 2){
printf("\nUsage: %s [filename]\n", argv[0]);
exit(1);
}
if((ptr = fopen(argv[1], "r")) == NULL){
perror("fopen");
exit(EXIT_FAILURE);
}
tmp = root;
printf("there are %d words in %s\n", words(ptr), argv[1]);
fclose(ptr);
if((ptr = fopen(argv[1], "r")) == NULL){
perror("fopen");
exit(EXIT_FAILURE);
}

root = wordCount(ptr);
printf("\"stffus = %s\"\n", root->w);
while(root != NULL){
printf("%s\n", root->w);
root = root->next;
}

return 0;
}

DrPizza
12-21-2002, 02:00 PM
I can't be bothered to read all that (C is horrid) but you know it's really bad style to cast the return value of malloc()?

You're clearly not writing C++ -- which needs the return value to be cast -- by virtue of the fact that you're creating variables named new. C has an implicit cast from void* to other pointer types, so there is no value in you putting in an explicit cast.

More to the point, the explicit cast can hide certain warnings that can indicate errors. If you accidentally omit to #include stdlib.h, malloc()'s prototype will not be visible. It will be assumed to be a function returning int and taking int. Casting an int to a pointer type can be done implicitly, but it typically generates a warning -- this warning will indicate that you haven't included the right header (malloc() shouldn't be returning int). The explicit cast will stifle the warning about the int cast, and so you won't notice your error so easily.

EscapeCharacter
12-22-2002, 03:33 AM
edit: cant delete this

EscapeCharacter
12-22-2002, 03:37 AM
ive always been told to do the typecast but it seems you are right, c99 standard says its not necessary but anyways. ive done some debugging and followed the value of list as it enters and leaves newWord. while in newWord everything seems to be going fine, malloc allocs memory for the new word and its value is changed from null to the new address, the wierd thing is when execution returns to wordCount list still equals null which doesnt make sense since i can see it being the value of the memory its pointing to. its almost like list is being copied into newWord instead of being passed by reference. heres the debug output.
while in newWord:

(gdb) print list
$2 = (word *) 0x8049d40


after execution returns to wordCount:

(gdb) print list
$3 = (word *) 0x0

ChefNinja
12-23-2002, 01:05 AM
This is kind of similar to the GPL contest thing we had.. isn't it?

stuka
12-23-2002, 01:07 AM
I'm pretty sure I know the problem here. I ran into it during my Data Structures class (all in C). You need to pass the address of your list into your function, because you're changing its value inside the function, which (as I'm sure you know) means you're only changing the VALUE passed to the function. Basically, change your newWord function to accept a word **, and replace list with *list inside the function. Of course, you'll have to change your call of the function to &list, but I'm sure this will clear up that particular error.

EscapeCharacter
12-23-2002, 05:09 AM
Originally posted by Stuka
I'm pretty sure I know the problem here. I ran into it during my Data Structures class (all in C). You need to pass the address of your list into your function, because you're changing its value inside the function, which (as I'm sure you know) means you're only changing the VALUE passed to the function. Basically, change your newWord function to accept a word **, and replace list with *list inside the function. Of course, you'll have to change your call of the function to &list, but I'm sure this will clear up that particular error.

so this only applies when you are dealing with structs? that may be why i couldnt figure out what was wrong ive never really used structs that much.

EscapeCharacter
12-23-2002, 09:24 AM
edit:
got a new problem everything is working now except when i run the program on the large file im suppose to run it on it seg faults ive check in gdb and i get this output


Program received signal SIGSEGV, Segmentation fault.
0x40090c18 in chunk_free (ar_ptr=0x40129cc0, p=0x999574a4) at malloc.c:3128
3128 malloc.c: No such file or directory.
(gdb)


i cant tell where exactly in my program that this is happening, i havent added free in anywhere yet but i dont think that could be causing it. here the only function i use malloc in.


word *newWord(char *chr, word **list){
word *new, *tmp;
if((*list) == NULL){
if(((word*)(*list) = malloc(sizeof(word))) == NULL){
perror("malloc");
exit(0);
}
if(((word*)(*list)->w = malloc(sizeof(char)*strlen(chr))) == NULL){
perror("malloc");
exit(0);
}
strcat((*list)->w, chr);
(*list)->count = 1;
(*list)->next = NULL;
return (*list);
}
else{
tmp = (*list);
while(tmp->next != NULL){
tmp = tmp->next;
}
if(((word*)new = malloc(sizeof(word))) == NULL){
perror("malloc");
exit(0);
}
if(((word*)new->w = malloc(sizeof(char)*strlen(chr))) == NULL){
perror("malloc");
exit(0);
}
strcat(new->w,chr);
new->count = 1;
new->next = NULL;
tmp->next = new;
return (*list);
}
}


this works fine when i run the program against smaller files say 100k but the 4meg one i want to use seg faults it, im new to working with files so bar with me. im pretty sure its not a memory issue i have 512megs and 400megs free so i must be doing something wrong.

stuka
12-23-2002, 11:39 AM
Just out of curiosity, what version of glibc are you working with? I ran into a similar problem on my box at home (running the glibc that ships w/Slack 8 ) that went away on Strike's box (newer) and the Solaris boxes at school.
And as for the structs, no. The reason it happened was this: when you pass a pointer to a function, just as when you pass an int, or char, or whatever, the function gets a COPY of the pointer. Since your function changes where the original pointer was pointing, it needs the ADDRESS of the pointer. The only reason you got the problems you did was because you were malloc()'ing a new pointer value, putting that in the copy, and then losing it when you returned to the calling function.

EscapeCharacter
12-23-2002, 11:52 AM
ive got glib 2.95.3, using slackware 8

stuka
12-23-2002, 11:56 AM
hmmm - could be the same problem I had then. Check the "Effin' malloc()" thread in this forum for a longer discussion of it (and what libs everyone else was using).

EscapeCharacter
12-23-2002, 12:01 PM
well im gonna check that out right now on my other box, i'll let you know if you were right(probably :))

EscapeCharacter
12-23-2002, 12:15 PM
well im still getting the same error in the debugger but with gcc 3.0.4 is going much further before dying, is there somewhere i cant check to see if gcc 3.0.4 has this same problem?

heres the backtrace if it helps any

Program received signal SIGSEGV, Segmentation fault.
0x40091c18 in chunk_free (ar_ptr=0x4012acc0, p=0x9998e49c) at malloc.c:3128
3128 malloc.c: No such file or directory.
(gdb) backtrace
#0 0x40091c18 in chunk_free (ar_ptr=0x4012acc0, p=0x9998e49c) at malloc.c:3128
#1 0x400918fa in chunk_alloc (ar_ptr=0x4012acc0, nb=16) at malloc.c:2615
#2 0x400910d4 in __libc_malloc (bytes=12) at malloc.c:2717
#3 0x8048743 in newWord ()
#4 0x804894b in wordCount ()
#5 0x8048a77 in main ()
#6 0x4003e2eb in __libc_start_main (main=0x80489b0 <main>, argc=2, ubp_av=0xbffffa24,
init=0x80484e0 <_init>, fini=0x8048c30 <_fini>, rtld_fini=0x4000c130 <_dl_fini>,
stack_end=0xbffffa1c) at ../sysdeps/generic/libc-start.c:129

stuka
12-23-2002, 12:56 PM
Well, that's a new gcc version - is the glibc version the same?

EscapeCharacter
12-23-2002, 01:08 PM
is there a command to find out which version of glibc i have? i think i have 2.2.3 but im not sure

stuka
12-23-2002, 01:36 PM
oh - I just looked in /usr/lib and followed the symlinks to get to the full name.

EscapeCharacter
12-23-2002, 01:38 PM
then yes i got 2.2.3

stuka
12-23-2002, 02:42 PM
That would be the same one I had problems with. I found this in the 2.2.5 Changelog:* Thu Mar 14 2002 Jakub Jelinek <jakub@redhat.com> 2.2.5-27
- update from CVS
- fix DST handling for southern hemisphere (#60747)
- fix daylight setting for tzset (#59951)
- fix ftime (#60350)
- fix nice return value
- fix a malloc segfault
- temporarily moved __libc_wait, __libc_fork and __libc_stack_end
back to what they used to be exported at
- censorship (#60758)(emphasis mine)

EscapeCharacter
12-23-2002, 02:48 PM
<mr burns>
execellent
</mr burns>
great now i have to upgrade, oh well its not like i have anything better to do :) thanks man

stuka
12-23-2002, 03:03 PM
yw - I really understand your frustration on this one - I was fighting a school project deadline over the summer when I ran into it!