动态内存分配与函数传参:如何修改函数中的动态/固定数组
如何在函数中修改动态数组与固定数组?
嘿,这个问题问得特别实在,日常写代码经常碰到!我分两种情况给你讲清楚,附上手写的代码例子,一看就懂~
一、动态分配的数组(用malloc/calloc创建的)
动态数组本质上是个指向堆内存的指针,处理起来分两种场景:
1. 只修改数组里的元素值
这种情况最简单,直接把数组指针传给函数就行。因为指针已经指向了堆上的内存区域,函数里通过指针就能直接修改对应位置的元素。
举个栗子:
#include <stdio.h> #include <stdlib.h> // 修改动态数组的元素 void updateDynamicArrayElements(int *arr, int size) { for (int i = 0; i < size; i++) { arr[i] = arr[i] * 2; // 把每个元素翻倍 } } int main() { int size = 5; int *dynamicArr = (int*)malloc(size * sizeof(int)); if (!dynamicArr) { perror("malloc failed"); return 1; } // 初始化数组 for (int i = 0; i < size; i++) { dynamicArr[i] = i + 1; } updateDynamicArrayElements(dynamicArr, size); // 打印修改后的结果 for (int i = 0; i < size; i++) { printf("%d ", dynamicArr[i]); // 输出:2 4 6 8 10 } free(dynamicArr); return 0; }
2. 需要修改数组的大小(比如扩容/缩容)
如果要给动态数组重新分配内存(比如realloc),这时候就不能只传普通指针了——因为realloc可能会返回新的内存地址,我们需要把这个新地址同步到主函数的指针变量里。这时候得传指针的指针(也就是int **arr)。
看代码:
#include <stdio.h> #include <stdlib.h> // 给动态数组扩容 void resizeDynamicArray(int **arr, int oldSize, int newSize) { // 重新分配内存,newSize是新的大小 int *temp = (int*)realloc(*arr, newSize * sizeof(int)); if (!temp) { perror("realloc failed"); return; } *arr = temp; // 把新的内存地址赋值给主函数里的指针 // 给新增的元素初始化(可选) for (int i = oldSize; i < newSize; i++) { (*arr)[i] = i + 1; } } int main() { int size = 3; int *dynamicArr = (int*)malloc(size * sizeof(int)); if (!dynamicArr) { perror("malloc failed"); return 1; } // 初始化原数组 for (int i = 0; i < size; i++) { dynamicArr[i] = i + 1; } // 扩容到5个元素 resizeDynamicArray(&dynamicArr, size, 5); size = 5; // 打印扩容后的数组 for (int i = 0; i < size; i++) { printf("%d ", dynamicArr[i]); // 输出:1 2 3 4 5 } free(dynamicArr); return 0; }
这里要注意:realloc可能会失败,所以一定要先判断返回值,别直接覆盖原指针,不然原内存地址会丢,造成内存泄漏。
二、固定大小的数组(栈上的数组,比如int arr[10])
固定数组的大小是编译期就确定好的,不能改大小,所以我们只能修改元素,或者把整个数组的内容替换掉。
1. 修改数组元素值
固定数组传参的时候会自动退化为指针,所以和动态数组修改元素的方式一样,直接传数组名就行,函数里通过指针操作元素。
例子:
#include <stdio.h> // 修改固定数组的元素 void updateFixedArray(int arr[], int size) { for (int i = 0; i < size; i++) { arr[i] += 10; // 每个元素加10 } } int main() { int fixedArr[5] = {1,2,3,4,5}; updateFixedArray(fixedArr, 5); // 打印结果 for (int i = 0; i < 5; i++) { printf("%d ", fixedArr[i]); // 输出:11 12 13 14 15 } return 0; }
这里要注意:函数里的arr[]其实就是int *arr,没法直接用sizeof(arr)获取数组的真实大小,所以必须手动传size参数。
2. 替换整个固定数组的内容
如果要把另一个数组的内容全部拷贝到固定数组里,因为固定数组大小不能变,所以只能用循环逐个赋值,或者用memcpy函数(效率更高)。
例子:
#include <stdio.h> #include <string.h> // 替换固定数组的全部内容 void replaceFixedArray(int dest[], const int src[], int size) { // 用memcpy批量拷贝,比循环快 memcpy(dest, src, size * sizeof(int)); // 或者用循环: // for (int i = 0; i < size; i++) { // dest[i] = src[i]; // } } int main() { int fixedArr[5] = {1,2,3,4,5}; int newArr[5] = {10,20,30,40,50}; replaceFixedArray(fixedArr, newArr, 5); // 打印替换后的结果 for (int i = 0; i < 5; i++) { printf("%d ", fixedArr[i]); // 输出:10 20 30 40 50 } return 0; }
这里要保证src数组的大小不超过dest的大小,不然会造成数组越界,触发未定义行为。
内容的提问来源于stack exchange,提问作者masiboo
相关产品推荐
相关产品推荐

