malloc 覆盖按值传递的参数

malloc overwrites argument passed by value

我想为二维数组分配内存,使数组的内存递增。这意味着 array[0] 可以容纳 1 个 uint32_t,数组 [1] 可以容纳 2 uint32_t,等等。可以把它想象成一个三角形。

我有一个函数将最终数组可以容纳的最大变量数作为参数 rows。所以我们有 rows 个数组(array[0]array[rows-1]),包含 1 到 rows 的多个变量。

为主数组初始化和分配内存后,我们可以使用for循环初始化然后为每个子数组增量分配。我们必须在两个单独的表达式中执行此操作,因为增量器 i 是继承可变的。

我们应该有这样的东西(我知道我没有 free 记忆但那不是问题):

#define ROWS 15

int main()
{
    uint32_t** array = triangle2array(FILEPATH, ROWS, DIGITS);
    ...
}

uint32_t** triangle2array(const char* filepath, uint8_t rows, uint8_t digits)
{
    uint32_t** row = (uint32_t**) malloc(rows*sizeof(uint32_t*));
    if (row == NULL) {
        fprintf(stderr, "row memory is not allocated\n");
        exit(EXIT_FAILURE);
    }
    for (size_t i = 0; i < rows; i++) {
        // Initialise memory for sub-array, i.e. arrays that hold the numbers on a specific row
        uint32_t* row[i];
        row[i] = (uint32_t*) malloc((i+1)*sizeof(uint32_t));
        if (row[i] == NULL) {
            fprintf(stderr, "row[%zi] memory is not allocated\n", i);
            exit(EXIT_FAILURE);
        }
        assert(rows == ROWS);
    }
    return row;
}

没用。根据调试器,参数 rows 被寻址到 0x00007FFFFFFFDFA4row[0] 被寻址到 0x00007FFFFFFFDFA0。本质上,row[0]rows 之前 4 个字节被寻址,当分配 malloc 时,内存被铺到 rows 上,给 rows 一个随机值。

奇怪的是,如果我制作一个镜像函数并做基本相同的事情,它会完美地工作:

#define MACRO 15

void example(uint8_t);

int main(void)
{
    example(MACRO);
    return 0;    
}

void example(uint8_t macro)
{
    uint32_t** row = malloc(macro*sizeof(uint32_t*));
    for (size_t i = 0; i < macro; i++) {
        uint32_t* row[i];
        row[i] = malloc((i+1)*sizeof(uint32_t));
    }
    assert(macro == MACRO);
    free(row);
}

老实说,我不知道如何解决这个问题。

    for (size_t i = 0; i < rows; i++) {
        // Initialise memory for sub-array, i.e. arrays that hold the numbers on a specific row
        uint32_t* row[i];
        row[i] = (uint32_t*) malloc((i+1)*sizeof(uint32_t));
        if (row[i] == NULL) {
            fprintf(stderr, "row[%zi] memory is not allocated\n", i);
            exit(EXIT_FAILURE);
        }
        assert(rows == ROWS);
    }

您的问题是第 uint32_t* row[i]; 行。我不知道你想要它做什么,但它实际上做的是声明一个名为 row 大小为 i 的新数组,位于 for 循环的主体。也就是说,下面的赋值

row[i] = (uint32_t*) malloc((i+1)*sizeof(uint32_t));

未分配给您之前 malloc 编辑的动态数组 row,但超出了此嵌套数组 row 的范围。删除虚假声明 uint32_t* row[i];,您的代码应该可以工作。