【问题标题】:Why I get realloc() invalid old size?为什么我得到 realloc() 无效的旧大小?
【发布时间】:2019-10-26 01:30:09
【问题描述】:

我正在尝试管理 4D 动态分配数组。 else 语句中的代码给了我错误。如果我不包含 else 语句,代码会正确,但这是一个好习惯吗?

int**** datind = (int****) malloc(nRow * sizeof(int***));
for (size_t i = 0; i < nRow; i++) {
    datind[i] = (int***) malloc(nCol * sizeof(int**));
}
for (size_t i = 0; i < nCol; i++) {
    for (size_t j = 0; j < nRow; j++) {
        datind[j][i] = (int**) malloc(1 * sizeof(int*));
    }
}

while ( fscanf(fp1, "%d %*c %d %*c %zu", &row, &col, &n_value) != EOF ) {
    if (n_value > 0) {
       datind[row-1][col-1] = (int**) realloc(datind[row-1][col-1], n_value * sizeof(int*));
       for (size_t i = 0; i < n_value; i++) {
           datind[row-1][col-1][i] = (int*) realloc(datind[row-1][col-1][i], 6 * sizeof(int));
           for (size_t j = 0; j < 6; j++) {
               fscanf(fp1,"%d%*c", &datind[row-1][col-1][i][j] );
           }
    } else {
       datind[row-1][col-1][0] = (int*) realloc(datind[row-1][col-1][0], 1 * sizeof(int));
       datind[row-1][col-1][0][0] = -1;
    }
}

3D 数组的类似代码,即以 int*** 开头,效果很好。

【问题讨论】:

  • (1) 如果发生错误,fscanf() 可以返回 EOF 以外的值。如果发生这种情况,正在读取的某些值不会被修改 - 如果它们未初始化,则使用它们的值会导致未定义的行为。 (2) 您没有对rowcol 进行任何范围检查。如果有任何为零,则使用 datind[row-1][col-1] 会给出未定义的行为。 (3) 未定义的行为不仅在else 中。 (4) 未定义的行为似乎可以工作,但这并不正确。
  • 您没有检查分配和重新分配的返回值来验证它们是否成功。这可能不会导致您描述的特定错误,但以后可能会咬到您。
  • 无论如何,为了回答调试问题,我们通常需要minimal reproducible example。提供的代码可以相当简单地包装成一个完整的程序,但是如果我们自己这样做,那么我们就不能确定捕获您可能遗漏的任何相关细节。此外,输入给程序的输入可能是一个因素,除非您告诉我们,否则我们不知道那是什么。
  • 长字符串中*的数量真的很难计算。如果您编写 int**** datind = malloc(nRow * sizeof *datind); ,阅读代码会容易得多。 (省略强制转换,其唯一目的是抑制您希望看到的编译器警告,并计算对象的大小而不是类型。)

标签: c++ dynamic-memory-allocation


【解决方案1】:

已解决!好的,这行得通。我在 cmets 中包含了提高代码质量的提示。不需要检查 row 和 col 是否等于 0,因为我知道它们可以从 1 变为 197。谢谢。

int **datind[(2*nx-1)][(2*ny-1)];

while ( fscanf(fp1, "%d %*c %d %*c %zu", &row, &col, &n_value) != EOF ) {

    if (n_value > 0) {

        datind[row-1][col-1] = (int**) malloc(n_value * sizeof(*datind));
        if (datind[row-1][col-1] == NULL) {
            printf("Memory allocation failed.\n");
            return EXIT_FAILURE;
        }

        for (size_t i = 0; i < n_value; i++) {
            datind[row-1][col-1][i] = (int*) malloc(6 * sizeof(*datind[row-1][col-1]));
            if (datind[row-1][col-1][i] == NULL) {
                printf("Memory allocation failed.\n");
                return EXIT_FAILURE;
            }

            for (size_t j = 0; j < 6; j++) {
                fscanf(fp1,"%d%*c", &datind[row-1][col-1][i][j] );
            }

        }
    } else {
        datind[row-1][col-1] = NULL;
    }

}

【讨论】:

    猜你喜欢
    • 2012-07-09
    • 2014-08-26
    • 2015-02-05
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多