c语言开辟二维数组_1_13
回到 3Sum 那题里,我们确实没有像“rowCount 循环 malloc 每一行”那样去分配二维数组的每一行空间;而是每找到一个解,就:
malloc(3个int)得到array(或triple)- 把这个指针直接放进
ans[ansTop]
这两种写法本质不同,但都合法。关键在于:你到底把“二维数组”理解成哪一种内存结构。
1)3Sum 那种返回值结构,本质是什么?
LeetCode 的签名是:
int** threeSum(...)
这意味着返回的是:
“指针数组 + 每行分别独立 malloc 的 int 数组”
也就是这种结构:
ans (int**,行指针数组)
│
├── ans[0] ──▶ [a, b, c] (malloc 3 个 int)
├── ans[1] ──▶ [a, b, c] (malloc 3 个 int)
├── ans[2] ──▶ [a, b, c] (malloc 3 个 int)
└── ...
注意:
✅ 每一行确实是独立开辟的(malloc(3*sizeof(int)))
只是它不是在“先开 rowCount 行”的循环里统一开,而是按需逐行生成。
2)你说的“没有循环开辟每行空间,而是直接存 array[]”
你的代码是这样:
int* array = malloc(3 * sizeof(int));
...
ans[ansTop++] = array;
是:
把“这一行的首地址”存进 ans 的某个位置
也就是存指针。
这一步的前提是:
✅ array 这行内存必须来自 malloc(或其他持久内存)
❌ 不能是局部数组,例如:
int array[3]; // ❌ 局部变量,函数结束就失效
ans[ansTop++] = array; // ❌ 悬空指针
3)为什么 3Sum 不适合用“先算 rowCount,再一次性循环开辟行”?
因为在 3Sum 里:
- 你一开始不知道会有多少个三元组(rowCount 不确定)
- 你也不知道结果会不会很多
- 所以通常做法是:
- 先给
ans一个容量 cap - 找到一个解就
malloc(3)生成一行 ans不够就realloc扩容
- 先给
这就是典型的“边生成边分配”。
4)两种二维数组分配方式对比(你要记住)
✅ A. 预先知道行数 rowCount(你刚才那段)
适用于:行数已知(比如读文件、固定矩阵)
ans = malloc(rowCount * sizeof(int*));
for i in rowCount:
ans[i] = malloc(colCount * sizeof(int));
特点:先把每行都分配好,再往里填。
✅ B. 行数未知(3Sum 这种)
适用于:结果数量不确定、动态增长
cap = 128;
ans = malloc(cap * sizeof(int*));
每找到一个解:
if ansTop == cap: realloc 扩容
row = malloc(3 * sizeof(int));
填 row
ans[ansTop++] = row;
特点:找到一行分配一行,按需增长。
5)你这句话里最关键的“正确点”
“并没有循环开辟二维数组的每行空间,而是直接复制 array[]”
- 如果
array是malloc出来的:✅ 这就是“逐行开辟”,完全正确 - 如果
array是栈数组:❌ 会出大错(悬空指针)

浙公网安备 33010602011771号