C语言函数中malloc/realloc数组后主函数段错误求助
Fixing Segmentation Fault When Modifying a Pointer via Function Calls in C
嘿,我一眼就看出问题所在了——你遇到的段错误和内存操作无效的根源,是指针传递的方式不对!你现在传的是int *C,这是典型的值传递,函数里修改的只是形参的副本,根本影响不到main函数里的那个C指针。
为什么会出问题?
当你把main里的C(初始是NULL)传入egyesit函数时,函数会创建一个局部的C变量,它是main中C的副本。你在函数里用malloc和realloc给这个局部C分配内存,但main里的C还是原来的NULL值。等函数执行完毕,局部C被销毁,你分配的内存就变成了没人能释放的“孤儿内存”(内存泄漏),而回到main后你去访问C[i],本质是在访问NULL指针指向的内存,直接触发段错误。
解决方案:传递指针的指针(int **C)
要让函数能修改main里的指针本身,你需要传递指针的指针——也就是把C的地址传给函数,这样函数就能直接操作main里的指针变量了。下面是修改后的完整代码:
1. 修改header.h中的函数声明
void egyesit(int *A, int *B, int **C, int n,int m,int *k);
2. 修改egyesit函数的实现
#include <stdio.h> #include <stdlib.h> void egyesit(int *A, int *B, int **C, int n, int m, int *k) { int i, j; // 给main里的C指针分配内存 *C = (int *)malloc(n * sizeof(int)); // 可选:检查malloc是否成功 if (*C == NULL) { fprintf(stderr, "Malloc failed to allocate memory!\n"); exit(EXIT_FAILURE); } *k = n; for (i = 0; i < n; i++) { printf("%d ", A[i]); (*C)[i] = A[i]; // 注意括号:[]优先级高于*,必须加括号才能正确访问数组元素 } printf("\n"); for (i = 0; i < *k; i++) { printf("%d ", (*C)[i]); } printf("\n"); int ok; for (i = 0; i < m; i++) { ok = 1; printf("%d ", B[i]); for (j = 0; j < *k; j++) { if ((*C)[j] == B[i]) { ok = 0; break; } } if (ok == 1) { *k = *k + 1; // 用临时变量接收realloc的返回值,避免分配失败时丢失原内存 int *temp = (int *)realloc(*C, *k * sizeof(int)); if (temp == NULL) { fprintf(stderr, "Realloc failed to allocate memory!\n"); free(*C); // 释放已分配的内存,避免泄漏 exit(EXIT_FAILURE); } *C = temp; (*C)[*k - 1] = B[i]; } } printf("\n"); for (i = 0; i < *k; i++) { printf("%d ", (*C)[i]); } printf("\n"); }
3. 修改main函数的调用
#include <stdio.h> #include <stdlib.h> #include "header.h" int main(){ int A[]={1,2,4,5,7}; int B[]={1,2,3,4,6,8}; int *C=NULL; int k=0; // 传递C的地址(指针的指针) egyesit(A,B,&C,5,6,&k); int i; for (i = 0; i < k; i++) { printf("%d ", C[i]); } printf("\n"); free(C); // 别忘了释放内存,避免泄漏 return 0; }
关键注意点
- 括号的重要性:
(*C)[i]必须加括号,因为数组下标运算符[]的优先级比解引用*高,如果写成*C[i]会被解释为*(C[i]),这会访问错误的内存地址。 - 内存分配检查:添加
malloc和realloc的返回值检查是良好的编程习惯,避免内存分配失败导致的未知错误。 - 释放内存:在main函数结束前一定要
free(C),否则会造成内存泄漏。
这样修改后,函数就能正确修改main里的C指针,分配的内存地址也能被main拿到,访问C[i]就不会触发段错误,内存也能正常释放了。
内容的提问来源于stack exchange,提问作者zarnilord
相关产品推荐
相关产品推荐

