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

不同计算机运行同一段C代码结果不一致的问题求助

为什么realloc后指针地址在不同机器上表现不一致?

先看看你提供的代码:

#include <stdlib.h> 
#include <stdio.h> 
void red(int *); 

int main() { 
    int *wsk,i; 
    wsk = (int*)malloc(10*sizeof(int)); 
    for(i=0;i<10;i++) { 
        wsk[i]=i+100; 
        printf("value: %d num pointer:%p \n",wsk[i],wsk+i); 
    } 
    printf("\n\n"); 
    red(wsk); 
    printf("\n\n"); 
    for(i=0;i<11;i++) { 
        printf("value: %d num pointer:%p \n",wsk[i],wsk+i); 
    } 
    free(wsk); 
    return 0; 
} 

void red(int* wsk) { 
    int i; 
    wsk = realloc(wsk,11*sizeof(int)); 
    for(i=0;i<11;i++) { 
        printf("value: %d num pointer:%p \n",wsk[i],wsk+i); 
    } 
}

你遇到的问题本质是C语言的参数值传递特性导致的,不同机器的内存分配策略放大了这个问题:

  • 说白了,你把main里的wsk传给red函数时,传的是这个指针的副本。red函数里对wsk的修改只会作用在这个副本上,完全不会影响main里的原始指针。
  • realloc的行为分两种情况:如果当前内存块后面有足够空间扩容,它会直接在原地址调整大小,返回原指针——这就是学校机器上出现的情况,所以red里的指针和main里的看起来一致,后续访问也没出问题;但如果原地址后面空间不够,realloc会分配一块新内存、拷贝旧数据、释放旧内存,这时候red里的wsk会指向新地址,但main里的指针还停在旧地址上,这就是你机器上出现的情况:后续main里循环访问11个元素时,越界访问了已经被释放的旧内存,就出现了乱码。

要解决这个问题,有两种靠谱的方式:

方式1:让red函数返回新的指针

修改red函数的返回值类型,把realloc后的指针返回给main:

#include <stdlib.h> 
#include <stdio.h> 

int* red(int *); // 修改函数声明

int main() { 
    int *wsk,i; 
    wsk = (int*)malloc(10*sizeof(int)); 
    if (wsk == NULL) { // 检查malloc是否失败
        fprintf(stderr, "malloc failed\n");
        return 1;
    }
    for(i=0;i<10;i++) { 
        wsk[i]=i+100; 
        printf("value: %d num pointer:%p \n",wsk[i],wsk+i); 
    } 
    printf("\n\n"); 
    wsk = red(wsk); // 接收返回的新指针
    if (wsk == NULL) { // 检查realloc是否失败
        fprintf(stderr, "realloc failed\n");
        return 1;
    }
    printf("\n\n"); 
    for(i=0;i<11;i++) { 
        printf("value: %d num pointer:%p \n",wsk[i],wsk+i); 
    } 
    free(wsk); 
    return 0; 
} 

int* red(int* wsk) { 
    int i; 
    wsk = realloc(wsk,11*sizeof(int)); 
    if (wsk == NULL) { // 检查realloc失败
        return NULL;
    }
    for(i=0;i<11;i++) { 
        printf("value: %d num pointer:%p \n",wsk[i],wsk+i); 
    }
    return wsk; // 返回新指针
}

方式2:传递二级指针(指针的指针)

通过传递指针的地址,让red函数直接修改main里的原始指针:

#include <stdlib.h> 
#include <stdio.h> 

void red(int **); // 修改函数声明为二级指针

int main() { 
    int *wsk,i; 
    wsk = (int*)malloc(10*sizeof(int)); 
    if (wsk == NULL) { // 检查malloc是否失败
        fprintf(stderr, "malloc failed\n");
        return 1;
    }
    for(i=0;i<10;i++) { 
        wsk[i]=i+100; 
        printf("value: %d num pointer:%p \n",wsk[i],wsk+i); 
    } 
    printf("\n\n"); 
    red(&wsk); // 传指针的地址
    printf("\n\n"); 
    for(i=0;i<11;i++) { 
        printf("value: %d num pointer:%p \n",wsk[i],wsk+i); 
    } 
    free(wsk); 
    return 0; 
} 

void red(int** wsk) { 
    int i; 
    *wsk = realloc(*wsk,11*sizeof(int)); // 修改原始指针的值
    if (*wsk == NULL) { // 检查realloc失败
        fprintf(stderr, "realloc failed\n");
        return;
    }
    for(i=0;i<11;i++) { 
        printf("value: %d num pointer:%p \n",(*wsk)[i],(*wsk)+i); // 访问指针指向的数组
    }
}

另外要记住:永远要检查malloc和realloc的返回值,如果内存分配失败,它们会返回NULL,不检查的话很容易导致程序崩溃。

内容的提问来源于stack exchange,提问作者aerodynamic96

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:07:17