c - valgrind 条件跳转或移动取决于未初始化
问题描述
Valgrind 对两行代码发出了两个警告,在每行代码旁边的评论中都提到了。
警告 1:
大小为 8 的无效写入,地址 ... 在大小为 9 的块中分配了 8 个字节
data[size] = NULL;
警告 2:
条件跳转或移动取决于未初始化的值
for (char **ptr = data; *ptr; ptr++) { // warning -> Conditional jump or move depends on uninitialized values(s)
free(*ptr);
}
这是一个完整的代码,
被调用者
char **getList() {
char **list = (char *[]) {"John", "Jane", NULL};
int size = 0;
for (char **ptr = list; *ptr; ptr++) {
size++;
}
char **data = malloc(sizeof(char *) * size + 1);
if (data == NULL) goto exception;
for (int i = 0; *list; list++, i++) {
data[i] = malloc(sizeof(char) * (strlen(*list) + 1));
if (data[i] == NULL) goto exception;
strcpy(data[i], *list);
}
data[size] = NULL; // this line gives warning
// warning -> invalid write of size 8, Address ... is 8 bytes inside a block of size 9 alloc'd
return data;
exception:
fprintf(stderr, "data allocation failed.\n");
return NULL;
}
调用者不同的文件/范围
char **data = getList();
for (char **ptr = data; *ptr; ptr++) { // warning -> Conditional jump or move depends on uninitialized values(s)
free(*ptr);
}
free(data);
解决方案
根据新石板上的建议写作。
编辑根据评论更新。
char **getList(void) {
const char * const list[] = {"John", "Jane", NULL};
unsigned int size = 0;
const char * const *ptr;
for (ptr = list; *ptr != NULL; ptr++) {
size++;
}
char **data = malloc(sizeof(char *) * (size + 1));
if (data == NULL) goto exception;
ptr = list;
for (unsigned int i = 0; *ptr != NULL; ptr++, i++) {
const size_t cache = strlen(*ptr) + 1;
data[i] = malloc(cache);
if (data[i] == NULL) goto exception;
memcpy(data[i], *ptr, cache);
}
data[size] = NULL;
return data;
exception:
fprintf(stderr, "Allocation failed.\n");
return NULL;
}
版本 2
在使用 C 字符串的帮助下:“与返回的局部变量相关的堆栈内存地址”
const char * const *getList(void) {
static const char * const list[] = {"John", "Jane", NULL};
return list;
}
推荐阅读
- python - 如何检查 int 输入是否在列表中?
- regex - Linux Bash grep 从匹配字符串中提取单词
- sql - 基于 WHERE 子句的 Liquibase 级联删除多对多
- python - Python - 6 个或更多尾部/头部代码的概率
- c - 是否将一个函数指针转换为等效函数,该函数指针接受一个 const 指针参数,但具有非常量指针参数可以吗?
- r - 在 dplyr 中使用 Select Helpers
- python - 将一个函数内部定义的变量传递给另一个函数
- discord - 时间计数器脚本 discord.js
- c# - 在场景大纲中运行每个示例后如何存储 ID?
- vue.js - 如何在类星体表中制作行跨度