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);
}
可能会出现问题,因为您的 dest1
和 dest2
字符串未 明确地 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
调用分配的内存将未初始化,并且您将进入未定义行为的领域! dest1
和 dest2
字符串的最后一个元素 可能 为零(这将使您的代码 看起来 有效)但它们可能不是 - 在这种情况下,printf
和 strcmp
调用将继续寻找,超出分配的内存缓冲区的末尾,寻找 'signal' NUL
终止符。
这里,你分配了5个字节的内存
char *dest1 = malloc(5 * sizeof(char));
在这里,您将字符串的 4 个字节复制到此缓冲区中
memcpy(dest1, src, 4);
这意味着,剩余的第 5 个字节未初始化。现在这里
strcmp(dest1, "FLSZ")
您将缓冲区与字符串 "FLSZ" 进行比较。这是通过逐字节比较前四个字符来执行的。
然后,strcmp()
访问第五个字节,因为字符串尚未终止。但是,这第五个字节未初始化。它可能是巧合的零字节,导致 strcmp()
工作,但 valgrind 检测到未初始化字节的访问并抱怨,条件 branch/jump 基于未初始化的值。
您可以通过在复制字符串后手动以零终止字符串来解决此问题。
我试图将这个 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);
}
可能会出现问题,因为您的 dest1
和 dest2
字符串未 明确地 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
调用分配的内存将未初始化,并且您将进入未定义行为的领域! dest1
和 dest2
字符串的最后一个元素 可能 为零(这将使您的代码 看起来 有效)但它们可能不是 - 在这种情况下,printf
和 strcmp
调用将继续寻找,超出分配的内存缓冲区的末尾,寻找 'signal' NUL
终止符。
这里,你分配了5个字节的内存
char *dest1 = malloc(5 * sizeof(char));
在这里,您将字符串的 4 个字节复制到此缓冲区中
memcpy(dest1, src, 4);
这意味着,剩余的第 5 个字节未初始化。现在这里
strcmp(dest1, "FLSZ")
您将缓冲区与字符串 "FLSZ" 进行比较。这是通过逐字节比较前四个字符来执行的。
然后,strcmp()
访问第五个字节,因为字符串尚未终止。但是,这第五个字节未初始化。它可能是巧合的零字节,导致 strcmp()
工作,但 valgrind 检测到未初始化字节的访问并抱怨,条件 branch/jump 基于未初始化的值。
您可以通过在复制字符串后手动以零终止字符串来解决此问题。