【问题标题】:Invalid Write Size of 8 Valgrind8 Valgrind 的无效写入大小
【发布时间】:2017-11-28 02:58:52
【问题描述】:

我正在编写一个函数来解析一个 .csv 文件,但我遇到了 valgrind 错误。具体来说是这样的:

==5450== Invalid write of size 8
==5450==    at 0x404FA0: parse_exemplars (util.c:568)
==5450==    by 0x40508E: get_test_and_train_data (util.c:595)
==5450==    by 0x402737: setup (pony_gp.c:727)
==5450==    by 0x4027E5: main (pony_gp.c:761)

这是带有错误行的代码:

csv_reader *reader = init_csv(file_name, ',');

double **fitness_cases, *targets;
int num_columns = 122;
int num_lines = 121;

// leave space for NULL at end
fitness_cases = malloc(sizeof(double **) * num_lines);
for (int i = 0; i < num_lines; i++) {
    fitness_cases[i] = malloc(sizeof(double *));

    for (int k = 0; k < num_columns; k++) {
        fitness_cases[i] = malloc(sizeof(double) * (num_columns - 1));
    }
}

// leave space for NAN at end
targets = malloc(sizeof(double) * (num_lines));

csv_line *row;
int f_i = 0;
int t_i = 0;

while ((row = readline(reader))) {
    int i;
    for (i = 0; i < num_columns; i++) {
        if (i == num_columns - 1) {
            targets[t_i++] = atof(row->content[i]);
        }
        else {
            fitness_cases[f_i][i] = atof(row->content[i]);
        }
    }

    fitness_cases[f_i][i-1] = (double)NAN; //<----- This is where it says the error is, line 568.
    f_i++;
}

每当我检查 Fitness_cases[f_i][i-1] 的大小时,我总是得到与 (double)NAN 大小相同的值,所以我猜它在函数中出现得更早?

github页面的链接是(我要问的这个功能目前在repo上没有更新):https://github.com/dyingpie1/pony_gp_c

【问题讨论】:

  • 分配代码完全没有意义。 for (int k...循环的目的是什么,它的body根本不依赖k,只是反复覆盖fitness_cases[i]的值,产生大量内存泄漏?
  • @Robbie:您似乎正在尝试创建一个二维数组fitness_cases。它是 二维 维的。然而,您有 三个 嵌套级别的内存分配。第三层从何而来?如上所述,第三个嵌套循环 for (int k... 毫无意义。
  • 哦,开头的分配是一个错字,我应该在嵌套循环中用 k 替换。我在发布之前简化了代码,但是在写的过程中出现了一些错误。
  • @Robbie 如果您在嵌套循环中将i 替换为k,那就更没有意义了。
  • @Robbie:替换变量在这里没有任何帮助。对于二维数组,您有三个嵌套级别的内存分配。那已经坏了。

标签: c csv valgrind


【解决方案1】:
fitness_cases[f_i][i-1] = (double)NAN; 

此处 i-1 的值将是 num_columns -1,但您已将空间分配为

fitness_cases[i] = malloc(sizeof(double) * (num_columns - 1));

第二个数组下标的最大索引可以少一,即 num_columns - 2,否则你会超出范围

例如

fitness_cases[i] = 3 * sizeof(double);

fitness_cases[i][0],fitness_cases[i][1],fitness_cases[i][2] 有效,fitness_cases[i][3] 超出范围,会导致无效写入,如 valgrind 所示

【讨论】:

    猜你喜欢
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 2017-06-29
    • 1970-01-01
    相关资源
    最近更新 更多