我有这个功能
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);
}
但是,当我尝试使用gdb调试这个时,比如显示name变量,我得到以下内容
(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"
这怎么可能有这么奇怪的行为? 我试图用这些mallocs操纵。我也尝试重写这个函数,这样我就可以举例说明如何重现它,但没有成功。
更奇怪的是,当我将malloc中的已分配空间更改为sizeof(char) * 99
时,结果是
(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"
答案 0 :(得分:2)
将字符串label_name
复制到一个缩短了9个字符的新变量name
。你复制所有字符减去最后9个字符。
此时,name
是未终止的C字符串,并且已使用其所有存储空间。在机器的内存中,name
之后会有更多的内存,但它不是你的,可以有任何数据。实际上,在您复制了最后一个字符后(并且您的malloced内存被纯粹的机会归零),您会看到不在您内存中的内容。
您将name
传递给函数function_get
,但该函数并不知道name
的长度。如果它会打印它,它可以正确打印name
,或者可以在它之后打印任何数据,直到它遇到空字符(如果它遇到一个;你不要&#39 ;知道那里有什么)。这就是所谓的未定义行为。
当您使用malloc
分配99个字符时,您说它仍然显示&#34;奇怪的行为&#34;。实际上,因为malloc
没有初始化内存,所以内存中可能有任何数据。虽然内存现在是你的(直到char 99),你仍然没有用\0
字符终止字符串,你仍然有未定义的行为。
获得的经验教训:终止您的字符串 \0
!!
答案 1 :(得分:0)
你永远不会空终止name
,也不会为空终止符分配足够的空间。此外,没有必要循环并通过这种方式复制字符。由于我们知道源字符串大于我们复制的长度,因此您应该能够做一个简单的memcpy
(否则strncpy
将是一个不错的选择)。所以也许看起来像这样:
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);
}