C malloc 和 memcpy 在拆分 char 数组时给出条件跳转 valgrind 错误

C memalloc & mempy give conditional jump valgrind error while splitting a char array

我试图将这个 char 数组分成两部分,第一个 4 个字符是一部分,其余的是第二部分它可以工作,但我在 valgrind 上遇到条件跳转问题 任何人都可以建议解决这个问题

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    const char src[50] = "FLSZGRGR";
    char *dest1 = malloc(5 * sizeof(char));
    memcpy(dest1, src, 4);
    printf("%s \n", dest1);
    if (strcmp(dest1, "FLSZ") == 0)
        printf("EQUAL 1 \n");

    char *dest2 = malloc(5 * sizeof(char));
    memcpy(dest2, src + 4, 4);
    printf("%s \n", dest2);
    if (strcmp(dest2, "GRGR") == 0)
        printf("EQUAL 2 \n");

    free(dest1);
    free(dest2);
    return (0);
}

可能会出现问题,因为您的 dest1dest2 字符串未 明确地 NUL 终止:调用 printf(使用 %s 格式)和 strcmp 要求 字符串以 NUL 结尾。

要解决此问题,您可以将最后一个 char 元素显式设置为 NUL 字符:

memcpy(dest1, src, 4);
dest1[4] = '[=10=]'; // Explicitly set NUL terminator (do the same for "dest2")

或使用 calloc 代替 malloc(这会将所有元素设置为零):

char *dest1 = calloc(5, sizeof(char)); // And similarly for "dest2"

如果没有其中任何一个,malloc 调用分配的内存将未初始化,并且您将进入未定义行为的领域dest1dest2 字符串的最后一个元素 可能 为零(这将使您的代码 看起来 有效)但它们可能不是 - 在这种情况下,printfstrcmp 调用将继续寻找,超出分配的内存缓冲区的末尾,寻找 'signal' NUL 终止符。

这里,你分配了5个字节的内存

char *dest1 = malloc(5 * sizeof(char));

在这里,您将字符串的 4 个字节复制到此缓冲区中

memcpy(dest1, src, 4);

这意味着,剩余的第 5 个字节未初始化。现在这里

strcmp(dest1, "FLSZ")

您将缓冲区与字符串 "FLSZ" 进行比较。这是通过逐字节比较前四个字符来执行的。

然后,strcmp() 访问第五个字节,因为字符串尚未终止。但是,这第五个字节未初始化。它可能是巧合的零字节,导致 strcmp() 工作,但 valgrind 检测到未初始化字节的访问并抱怨,条件 branch/jump 基于未初始化的值。

您可以通过在复制字符串后手动以零终止字符串来解决此问题。