Reputation: 15
I'm trying to add a new node to a struct with a char* field (word)
Definition of listT:
enum boolean {false, true};
struct list {
enum boolean sorted;
union{
int words;
char *word;
};
struct list* next;
struct list* previous;
};
typedef struct list listT;
add_word_node function is being called by main as: add_word_node(read_word, list_head)
where read_word
is given by the user with scanf. Word is being pass as a string but after strncpy there is no terminating byte.
>Debugger:
add_word_node (word=0xbffff0fa "ally", head=0x804c038) at prog.c
>Debugger:
(gdb) p newnode->word
$2 = 0x804c068 "allyP\224\373\267\377\377\377\377"
listT *add_word_node(char word[], listT *head) {
listT *newnode;
listT *curr = NULL;//sorted
//listT *prev;//sorted
newnode = malloc(sizeof(listT)); /* allocate new node and check */
newnode->word = malloc(sizeof(char)* WORDLEN);
strncpy(newnode->word, word, strlen(word));
//newnode->word = strndup(word, strlen(word));
if (newnode == NULL) {
return (NULL);
}
if (head->sorted == false){ //eisagwgh sto telos ths listas
newnode->next = head;
head->previous->next = newnode;
newnode->previous = head->previous;
head->previous = newnode;
}else {
if(head->next == head){
newnode->next = head;
newnode->previous = head;
head->next = newnode;
head->previous = newnode;
}else{
for (curr = head->next; curr->next != NULL; curr = curr->next){//for( curr = head->next; ;){
if(curr == NULL) break;
if(strncmp(curr->word,newnode->word,strlen(word)) > 0) break;
//else curr= curr->next;
}
if(strncmp(curr->word,newnode->word,strlen(word))== 0){
return(curr);
}
newnode->next = curr;
newnode->previous = curr->previous;
newnode->previous->next = newnode;
newnode->next->previous = newnode;
}
}
return (newnode);
}
I have read some other topics about this problem and I changed the function to use word[] instead of char* but it still doesn't work. Please tell me if you need more info. Also, when I use strndup, it sometimes work without any error.
Upvotes: 0
Views: 239
Reputation: 2702
To expand @Gopi's answer a bit:
Your statement
newnode = (listT *) malloc(sizeof(listT) + WORDLEN);
allocates memory to the pointer newnode
. This means that, for example if WORDLEN
is the same as sizeof(listT)
, then you will be allocating memory for two listT
elements for newnode
. This is similar to, say, char *ptr = malloc(2);
which will allocate memory for two char
elements for ptr
.
TL;DR: This WORDLEN
memory will NOT be allocated to newnode->word
, it is allocated to newnode
, and that's that. To fix your problem, you must allocate memory to newnode->word
separately. newnode
does not need that memory, but newnode->word
does.
strndup()
works because it allocates the memory for you.
If you still struggle to understand this, you may have some misconceptions on pointers.
newnode->word
is a pointer. It has a fixed size on a certain machine (e.g. 8 bytes). For simplicity assume listT
is defined as follows:
typedef struct {
char *word;
} listT;
Then when you allocate memory, you only need to allocate 8 bytes to newnode
so that it can hold one pointer, and then you need to allocate memory to that pointer, which will be used to store some characters.
malloc()
. See Do I cast the result of malloc?
Upvotes: 0
Reputation: 19874
As you say you have a char *word
then this pointer should be allocated memory
newnode->word = malloc(sizeof(char) * (WORDLEN+1)); /* Please access the structure elements accordingly */
Memory should be allocated to the pointer before writing something to it.
Upvotes: 0