mxwawaawxm 发表于 2020-9-20 19:57

c语言realloc函数疑惑

本帖最后由 mxwawaawxm 于 2020-9-20 20:00 编辑

之前看视频时,听到函数参数传递时,是值参递。也就是函数内部会新建一个变量存放实参的值
所以在main函数通过malloc函数动态分配内存,赋予了变量arr6个int大小的字节;而后在gen(int *arr)里调用realloc函数扩大内存,把它扩大到8个int
最后,居然外部的arr也跟着扩大了。而且gen函数内部、main函数外部运行的打印结果是一致的{:301_982:}
#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变量
结果,编译没报错。运行出现随机值

#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");   
}


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

#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");   
}


后面两个测试代码,到底是哪里出错了,请大侠们指点下{:301_1009:}

我的爱是你 发表于 2020-9-20 20:26

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

没仔细审题/

珍惜浮华 发表于 2020-9-20 20:36

谢谢楼主分享{:1_911:}{:1_911:}{:1_911:}

mxwawaawxm 发表于 2020-9-20 20:38

我的爱是你 发表于 2020-9-20 20:26
不懂你意思。
reallos直接对数组重新开辟大了2个int   在堆区你外部数组当然也会改变。
至于第二个说到底 ...

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

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

    print_arr(arr, 8);

    free(temp);

指针交换,请问什么意思
*(arr+6) = *(temp+0);
*(arr+7) = *(temp+1);

这里不是在修改arr、arr的值吗。

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

而且其余arr的值都乱了

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地址

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

A地址自动被释放了,但是gen函数并没有把现在的arr地址返回主函数

所以在主函数中arr还是A地址,但这时候A地址已经被释放了,所以是随机数,并且free函数想释放的还是A地址,可能会产生错误。

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

mxwawaawxm 发表于 2020-9-22 21:57

volcanst 发表于 2020-9-20 23:20
假设使用realloc函数之前arr是A地址

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


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

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

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

另外,你这调试是VS自带的调试器,还能查看地址。不知道gdb能否{:301_998:}
#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");   
}
页: [1] 2
查看完整版本: c语言realloc函数疑惑