方阵的动态重新分配
Dynamic reallocation of a square matrix
我正在尝试创建一个函数,每次我需要时,它都会动态地向方矩阵添加 1 行和 1 列。我将代码作为示例发布,我从一个整数的“1x1 矩阵”开始,我尝试添加一行和一列 5 次以获得最后一个 5x5 矩阵,我不明白为什么 OS 立即停止执行。在 for 循环中,我首先重新分配 "column" 指针数组,添加一个新指针(因此是新行),然后为它的每个块(因此对于每一行)我重新分配其他 N 个内存块。似乎我试图访问一个被禁止的内存地址,但我不明白为什么,出了什么问题?
P.S: 我的英语不是很完美所以如果你不明白我想说什么我会解释得更好。
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
int **M,N;
int main(int argc, char** argv) {
N = 1;
M = (int**)malloc(sizeof(int*));
M[0] = (int*)malloc(sizeof(int));
for (int i = 0; i < 5; i++) {
N++;
M = (int**)realloc(M, N * sizeof(int*));
for (int k=0; k<N; k++)
M[k] = (int*)realloc(M[k], N * sizeof(int));
}
}
在进入循环之前,您有 M
指向单个 int *
和 M[0]
指向单个 int
.
在循环的第一次迭代中,您使用 realloc
修改 M
以指向 2 int *
的数组。第一个仍然指向单个 int
,但第二个未初始化。当您随后尝试在 M[1]
上调用 realloc
时,它会读取一个未初始化的指针来调用 undefined behavior。在这种情况下,它表现为崩溃。
您需要将新添加的M
元素初始化为NULL
,这样realloc
才能正常工作
M = realloc(M, N * sizeof(int*));
M[N-1] = NULL;
for (int k=0; k<N; k++) {
M[k] = realloc(M[k], N * sizeof(int));
}
此外,don't cast the return value of malloc
/realloc
使用realloc展开数组时,数组中新展开的元素并没有被初始化。所以当你realloc M时,指向内存的附加指针是未定义的,不是NULL,所以你不能在第二次realloc中引用M[]的扩展元素,直到你将它们初始化为NULL。
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
int **M,N;
int main(int argc, char** argv) {
N = 1;
M = (int**)malloc(sizeof(int*));
M[0] = (int*)malloc(sizeof(int));
for (int i = 0; i < 5; i++) {
N++;
M = (int**)realloc(M, N * sizeof(int*));
// Ensure the last M[] is NULL
M[N-1] = NULL;
for (int k=0; k<N; k++)
M[k] = (int*)realloc(M[k], N * sizeof(int));
}
}
我正在尝试创建一个函数,每次我需要时,它都会动态地向方矩阵添加 1 行和 1 列。我将代码作为示例发布,我从一个整数的“1x1 矩阵”开始,我尝试添加一行和一列 5 次以获得最后一个 5x5 矩阵,我不明白为什么 OS 立即停止执行。在 for 循环中,我首先重新分配 "column" 指针数组,添加一个新指针(因此是新行),然后为它的每个块(因此对于每一行)我重新分配其他 N 个内存块。似乎我试图访问一个被禁止的内存地址,但我不明白为什么,出了什么问题? P.S: 我的英语不是很完美所以如果你不明白我想说什么我会解释得更好。
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
int **M,N;
int main(int argc, char** argv) {
N = 1;
M = (int**)malloc(sizeof(int*));
M[0] = (int*)malloc(sizeof(int));
for (int i = 0; i < 5; i++) {
N++;
M = (int**)realloc(M, N * sizeof(int*));
for (int k=0; k<N; k++)
M[k] = (int*)realloc(M[k], N * sizeof(int));
}
}
在进入循环之前,您有 M
指向单个 int *
和 M[0]
指向单个 int
.
在循环的第一次迭代中,您使用 realloc
修改 M
以指向 2 int *
的数组。第一个仍然指向单个 int
,但第二个未初始化。当您随后尝试在 M[1]
上调用 realloc
时,它会读取一个未初始化的指针来调用 undefined behavior。在这种情况下,它表现为崩溃。
您需要将新添加的M
元素初始化为NULL
,这样realloc
才能正常工作
M = realloc(M, N * sizeof(int*));
M[N-1] = NULL;
for (int k=0; k<N; k++) {
M[k] = realloc(M[k], N * sizeof(int));
}
此外,don't cast the return value of malloc
/realloc
使用realloc展开数组时,数组中新展开的元素并没有被初始化。所以当你realloc M时,指向内存的附加指针是未定义的,不是NULL,所以你不能在第二次realloc中引用M[]的扩展元素,直到你将它们初始化为NULL。
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
int **M,N;
int main(int argc, char** argv) {
N = 1;
M = (int**)malloc(sizeof(int*));
M[0] = (int*)malloc(sizeof(int));
for (int i = 0; i < 5; i++) {
N++;
M = (int**)realloc(M, N * sizeof(int*));
// Ensure the last M[] is NULL
M[N-1] = NULL;
for (int k=0; k<N; k++)
M[k] = (int*)realloc(M[k], N * sizeof(int));
}
}