Reputation: 6132
I am writing a program and have the following loop:
while ((c = getchar()) != EOF){
if (c == '\n'){
char newword[strlen(word) + 1];
strcpy(newword, word);
words[i].key = newword;
memset(word, '\0', MAXLENGTH);
i++;
j = 0;
} else {
word[j++] = c;
}
}
Where words
is an array of structures:
struct kvp{
char *key;
int line;
};
and word
is a big array (of size MAXLENGTH
), the first few values of which constitute a string.
The problem rests with words[i].key
. Within the if statement, printing it (after setting it to newword
) will return the correct value, namely, an minimally-sized string that is the same as the word that was entered. Once the if statement is exited and we're back in the outer body of the while loop, however, it changes to something completely random, i.e. ?HBk?
.
There are three things I suspect could be happening:
strcpy
doesn't act the way I think it doesnewword
is a local variable and that somehow affects things (doesn't sound right)What is going on?
Upvotes: 1
Views: 1514
Reputation: 59617
When you declare newword
in the if
block, it goes out of scope after that block exits. If you want it to persist, you'll need to either allocate memory in an outer scope, or allocate the string on the heap with malloc
.
if (c == '\n')
{
// newword will persist beyond this block:
char *newword = malloc(strlen(word) + 1);
strcpy(newword, word);
words[i].key = newword;
Note that now you'll need to call free
on this alloc'd block, or create a memory leak. At some later point you'll need to call free(words[i].key)
.
Martin's suggestion of using strdup
is a good one, it strdup
is available: it will do the alloc for you - but you'll still need to free
later.
Upvotes: 4
Reputation: 3753
newword is being stored on the stack, so it will go out of scope each time the while loop executes.
You need to dynamically allocate memory for it. I'd suggest replacing
char newword[strlen(word) + 1];
strcpy(newword, word);
with:
char * newword = strdup(word);
This will allocate the memory and copy the contents across. Be aware, you should clean up that memory later with free(), otherwise you'll have a memory leak.
Upvotes: 2