C处理字符时的奇怪行为*

C处理字符时的奇怪行为*,c,C,我有这个函数 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 f

我有这个函数

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);
}
怎么会有这么奇怪的行为? 我试图操纵这些马洛克人。我还试图重写函数,以便给您一个如何复制它的示例,但没有成功

更奇怪的是,当我将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"

将字符串
label\u name
复制到一个新变量
name
,该变量短9个字符。复制除最后9个字符之外的所有字符

此时,
name
是一个未终止的C字符串,其所有存储都已被使用。在机器的内存中,
name
之后会有更多内存,但它不是您的,可以有任何数据。事实上,在你复制了最后一个字符之后(你的malloced内存完全是偶然归零的),你看到了内存中的东西,而不是你的内存

您将
name
传递给函数
function\u get
,但是,该函数不知道
name
有多长。如果它要打印它,它可以正确地打印
name
,或者可以打印它后面的任何数据,直到它遇到一个空字符(如果它遇到一个空字符;您不知道有什么)。这就是所谓的未定义行为

当您使用
malloc
分配99个字符时,您说它仍然显示“奇怪的行为”。实际上,因为malloc不初始化内存,所以内存中可能有任何数据。虽然内存现在是您的(最多为char 99),但您仍然没有使用
\0
字符终止字符串,并且仍然有未定义的行为


经验教训:使用
\0
终止字符串

将字符串
label\u name
复制到一个新变量
name
,该变量短9个字符。复制除最后9个字符之外的所有字符

此时,
name
是一个未终止的C字符串,其所有存储都已被使用。在机器的内存中,
name
之后会有更多内存,但它不是您的,可以有任何数据。事实上,在你复制了最后一个字符之后(你的malloced内存完全是偶然归零的),你看到了内存中的东西,而不是你的内存

您将
name
传递给函数
function\u get
,但是,该函数不知道
name
有多长。如果它要打印它,它可以正确地打印
name
,或者可以打印它后面的任何数据,直到它遇到一个空字符(如果它遇到一个空字符;您不知道有什么)。这就是所谓的未定义行为

当您使用
malloc
分配99个字符时,您说它仍然显示“奇怪的行为”。实际上,因为malloc不初始化内存,所以内存中可能有任何数据。虽然内存现在是您的(最多为char 99),但您仍然没有使用
\0
字符终止字符串,并且仍然有未定义的行为


经验教训:使用
\0
终止字符串

您从未使用空终止符
名称
,也没有为空终止符分配足够的空间。而且,不需要通过这种方式循环复制字符。因为我们知道源字符串大于我们要复制的长度,所以您应该能够执行一个简单的
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);
}

您从未使用空终止符
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);
}

您的输入和预期输出是什么?另外,您面临的问题是什么?输入是“multiply2\u函数”,预期输出是“multiply2”。您从未使用
'\0'
终止
name
。即使我这样做了,它也不会改变这样一个事实:for循环一次填充多个字符,我觉得应该是这样的impossible@JohnnyMopp这是对的。您从不使用
\0
终止字符串,这就是为什么您会有这种奇怪的情况(您的大部分内存将被初始化为null,因此您不会有任何问题,但您不能依赖这一事实),这就是为什么您应该使用valgrind之类的工具,当你访问单元化内存时,它们会告诉你。你的输入和预期输出是什么?另外,您面临的问题是什么?输入是“multiply2\u函数”,预期输出是“multiply2”。您从未使用
'\0'
终止
name
。即使我这样做了,它也不会改变这样一个事实:for循环一次填充多个字符,我觉得应该是这样的impossible@JohnnyMopp这是对的。你永远不会用
\0
来终止字符串,这就是为什么你会有这样的奇怪(你的大部分内存将被初始化为空,因此你不会有任何问题,但你不能依赖这一事实),这就是为什么你应该使用valgrind之类的工具,当你访问单元化内存时,它们会告诉你。