首页 > 解决方案 > 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);

标签: cvalgrind

解决方案


根据新石板上的建议写作。

编辑根据评论更新。

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;
}

推荐阅读