Reputation: 260
I've got this function
Function *function_get_by_label(char *label_name) {
int new_len = strlen(label_name) - 9;
char* name = malloc(sizeof(char) * new_len);
for (int i = 0; i < new_len; i++) {
name[i] = label_name[i];
}
return function_get(name);
}
however, when I try to debug this one with gdb, like display the name variable, I get the following
(gdb) display name
1: name = 0x610120 ""
(gdb) n
1: name = 0x610120 ""
1: name = 0x610120 "m"
1: name = 0x610120 "m"
1: name = 0x610120 "mu"
1: name = 0x610120 "mu"
1: name = 0x610120 "mul"
1: name = 0x610120 "mul"
1: name = 0x610120 "mult"
1: name = 0x610120 "mult"
1: name = 0x610120 "multi"
1: name = 0x610120 "multi"
1: name = 0x610120 "multip"
1: name = 0x610120 "multip"
1: name = 0x610120 "multipl"
1: name = 0x610120 "multipl"
1: name = 0x610120 "multiply2_function"
How is that possible that there's such a weird behavior? I tried to manipulate with these mallocs. I also tried to rewrite the function so I can give you an example how to reproduce it, but without a success.
Even more weird thing is, when I change allocated space in malloc to sizeof(char) * 99
, the result is
(gdb) display name
1: name = 0x60f120 ""
(gdb) n
1: name = 0x60f120 ""
1: name = 0x60f120 "m"
1: name = 0x60f120 "m"
1: name = 0x60f120 "mu"
1: name = 0x60f120 "mu"
1: name = 0x60f120 "mul"
1: name = 0x60f120 "mul"
1: name = 0x60f120 "mult"
1: name = 0x60f120 "mult"
1: name = 0x60f120 "multi"
1: name = 0x60f120 "multi"
1: name = 0x60f120 "multip"
1: name = 0x60f120 "multip"
1: name = 0x60f120 "multipl"
1: name = 0x60f120 "multipl"
1: name = 0x60f120 "multiplyltiply2_function"
Upvotes: 0
Views: 123
Reputation: 4370
You never null-terminate name
, nor do you allocate enough space for the null terminator. Also, there's no need to loop through and copy the characters over that way. Since we know the source string is greater than the length we are copying, you should be able to do a simple memcpy
(otherwise strncpy
would be a good choice). So maybe something that looks like this:
Function *function_get_by_label(char *label_name) {
int new_len = strlen(label_name) - 8;
char* name = malloc(sizeof(char) * new_len);
memcpy(label_name, name, new_len-1);
name[new_len-1] = '\0';
return function_get(name);
}
Upvotes: 0
Reputation: 25286
You copy the string label_name
to a new variable name
that is 9 characters shorter. You copy all characters minus these last 9.
At this point, name
is an unterminated C-string and all its storage has been used. In the machine's memory, there will be more memory after name
but it is not yours and can have any data. Indeed, after you copied the last character (and your malloced memory was by pure chance zeroed), you see what is in the not-your-memory.
You pass name
to a function function_get
, however, that function doesn't know how long name
is. If it would print it, it could print name
correctly, or can print any data after it, until it encounters a null-character (if it encounters one at all; you don't know what is there). This is what is called undefined behavior.
When you allocate 99 characters with malloc
you say it still shows "weird behavior". Indeed, because malloc
doesn't initialize the memory so there could be any data in the memory. Although the memory now is yours (up to char 99), you still haven't terminated the string with a \0
character and you still have undefined behavior.
Lesson learned: terminate your strings with \0
!!
Upvotes: 2