You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:29:08