我想为 2D 数组分配内存,以便数组具有增加的增量内存。这意味着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 allocatedn");
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 allocatedn", i);
exit(EXIT_FAILURE);
}
assert(rows == ROWS);
}
return row;
}
它不起作用。根据调试器,参数rows
被寻址给0x00007FFFFFFFDFA4
,而row[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 allocatedn", 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
edrow
的动态数组,而是超出此嵌套数组的边界row
。删除虚假声明uint32_t* row[i];
,您的代码应该可以工作。