吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1232|回复: 12
收起左侧

[求助] c语言realloc函数疑惑

[复制链接]
mxwawaawxm 发表于 2020-9-20 19:57
本帖最后由 mxwawaawxm 于 2020-9-20 20:00 编辑

之前看视频时,听到函数参数传递时,是值参递。也就是函数内部会新建一个变量存放实参的值
所以在main函数通过malloc函数动态分配内存,赋予了变量arr6个int大小的字节;而后在gen(int *arr)里调用realloc函数扩大内存,把它扩大到8个int
最后,居然外部的arr也跟着扩大了。而且gen函数内部、main函数外部运行的打印结果是一致的
2020-09-20_195948.png
[C] 纯文本查看 复制代码
#include <stdio.h>#include <stdlib.h>
#include <time.h>

void gen(int *arr);
void print_arr(int *arr, int num);

int main(int argc, const char *argv[])
{
    srand(time(NULL));
    int *arr = (int *)malloc(sizeof(int)*6);

    gen(arr);

    print_arr(arr, 8);

    free(arr);

    return 0;
}


void gen(int *arr)
{
    int i;

    for (i=0;i<6;i++) {
        *(arr+i) = rand()%9+1;
    }

    arr = (int *)realloc(arr, sizeof(int)*8);

    *(arr+6) = rand()%9+1;
    *(arr+7) = rand()%9+1;

    print_arr(arr, 8);
}

void print_arr(int *arr, int num)
{
    int i;

    printf("%s\n", __FUNCTION__);
    for (i=0;i<8;i++) {
        printf("%d ", *(arr+i));
    }
    printf("\n");    
}


接着,做了个测试,在gen函数内部通过malloc函数动态分配内存,赋予temp变量2个int大小的字节,并赋值
最后再赋值给arr变量
结果,编译没报错。运行出现随机值
2020-09-20_195601.png
[C] 纯文本查看 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void gen(int *arr);
void print_arr(int *arr, int num);

int main(int argc, const char *argv[])
{
    srand(time(NULL));
    int *arr = (int *)malloc(sizeof(int)*6);

    gen(arr);

    print_arr(arr, 8);

    free(arr);

    return 0;
}


void gen(int *arr)
{
    int i;
    int *temp = (int *)malloc(sizeof(int)*2);

    for (i=0;i<2;i++) {
        *(temp+i) = rand()%9+1;
    }

    for (i=0;i<6;i++) {
        *(arr+i) = rand()%9+1;
    }

    arr = (int *)realloc(arr, sizeof(int)*8);

    *(arr+6) = *(temp+0);
    *(arr+7) = *(temp+1);

    print_arr(arr, 8);

    free(temp);
}

void print_arr(int *arr, int num)
{
    int i;

    printf("%s\n", __FUNCTION__);
    for (i=0;i<8;i++) {
        printf("%d ", *(arr+i));
    }
    printf("\n");    
}



后面又再做了一次测试,依旧编译通过,但运行出错

[C] 纯文本查看 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void gen(int *arr, int *temp);
void print_arr(int *arr, int num);

int main(int argc, const char *argv[])
{
    srand(time(NULL));
    int *arr = (int *)malloc(sizeof(int)*6);
    int *temp = NULL;

    gen(arr, temp);

    print_arr(arr, 8);

    free(arr);
    free(temp);

    return 0;
}


void gen(int *arr, int *temp)
{
    int i;
    temp = (int *)realloc(temp, sizeof(int)*2);

    for (i=0;i<2;i++) {
        *(temp+i) = rand()%9+1;
    }

    for (i=0;i<6;i++) {
        *(arr+i) = rand()%9+1;
    }

    arr = (int *)realloc(arr, sizeof(int)*8);

    *(arr+6) = *(temp+0);
    *(arr+7) = *(temp+1);

    print_arr(arr, 8);
}

void print_arr(int *arr, int num)
{
    int i;

    printf("%s\n", __FUNCTION__);
    for (i=0;i<8;i++) {
        printf("%d ", *(arr+i));
    }
    printf("\n");    
}



后面两个测试代码,到底是哪里出错了,请大侠们指点下
2020-09-20_195052.png

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

我的爱是你 发表于 2020-9-20 20:26
本帖最后由 我的爱是你 于 2020-9-20 20:35 编辑

没仔细审题/
珍惜浮华 发表于 2020-9-20 20:36
 楼主| mxwawaawxm 发表于 2020-9-20 20:38
我的爱是你 发表于 2020-9-20 20:26
不懂你意思。
reallos直接对数组重新开辟大了2个int   在堆区你外部数组当然也会改变。
至于第二个说到底 ...

[C] 纯文本查看 复制代码
    arr = (int *)realloc(arr, sizeof(int)*8);
 
    *(arr+6) = *(temp+0);
    *(arr+7) = *(temp+1);
 
    print_arr(arr, 8);
 
    free(temp);


指针交换,请问什么意思
[C] 纯文本查看 复制代码
*(arr+6) = *(temp+0);
*(arr+7) = *(temp+1);


这里不是在修改arr[6]、arr[7]的值吗。

最后释放temp的内存空间,怎么会连arr[6~7]的值都给释放掉了

而且其余arr[0~5]的值都乱了
silverkey 发表于 2020-9-20 20:56
跟内存分配有关系,你可以开个虚拟机,上个dos7.0试一试就知道是不是这回事了
callmemabey 发表于 2020-9-20 21:04
建议你好好看看realloc的作用
我是孙伯 发表于 2020-9-20 21:08
百度百科:realloc重分配成功旧内存会被自动释放,旧指针变成了野指针。
在gen函数里更新的指针并没有传回到主函数中。
回到主函数后,打印野指针所以随机打印乱数。free野指针所以程序崩溃。
头像被屏蔽
沐雨红尘 发表于 2020-9-20 21:35
提示: 作者被禁止或删除 内容自动屏蔽
volcanst 发表于 2020-9-20 23:20
本帖最后由 volcanst 于 2020-9-20 23:27 编辑

假设使用realloc函数之前arr是A地址
1.png
使用之后arr就变成了B地址
2.jpg
A地址自动被释放了,但是gen函数并没有把现在的arr地址返回主函数
3.png
所以在主函数中arr还是A地址,但这时候A地址已经被释放了,所以是随机数,并且free函数想释放的还是A地址,可能会产生错误。

所以只需要在gen函数中返回arr的地址就可以了
4.png

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
mxwawaawxm + 1 + 1 热心回复!

查看全部评分

 楼主| mxwawaawxm 发表于 2020-9-22 21:57
volcanst 发表于 2020-9-20 23:20
假设使用realloc函数之前arr是A地址

使用之后arr就变成了B地址

谢谢。那为啥,第一串源代码里,同样也采用realloc函数,但在主函数里能正确打印

照你图示来看,下面这串代码,在gen函数里,调用realloc函数,arr不是也会更改地址?

gen函数同样也没把arr新地址传给主函数,但最后却能正确打印

另外,你这调试是VS自带的调试器,还能查看地址。不知道gdb能否
[C] 纯文本查看 复制代码
#include <stdio.h>#include <stdlib.h>
#include <time.h>
 
void gen(int *arr);
void print_arr(int *arr, int num);
 
int main(int argc, const char *argv[])
{
    srand(time(NULL));
    int *arr = (int *)malloc(sizeof(int)*6);
 
    gen(arr);
 
    print_arr(arr, 8);
 
    free(arr);
 
    return 0;
}
 
 
void gen(int *arr)
{
    int i;
 
    for (i=0;i<6;i++) {
        *(arr+i) = rand()%9+1;
    }
 
    arr = (int *)realloc(arr, sizeof(int)*8);
 
    *(arr+6) = rand()%9+1;
    *(arr+7) = rand()%9+1;
 
    print_arr(arr, 8);
}
 
void print_arr(int *arr, int num)
{
    int i;
 
    printf("%s\n", __FUNCTION__);
    for (i=0;i<8;i++) {
        printf("%d ", *(arr+i));
    }
    printf("\n");    
}
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 12:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表