c语⾔中realloc()函数解析
⼀、基本特性
1、 realloc()函数可以重⽤或扩展以前⽤malloc()、calloc()及realloc()函数⾃⾝分配的内存。
2、 realloc()函数需两个参数:⼀个是包含地址的指针(该地址由之前的malloc()、calloc()或realloc()函数返回),另⼀个是要新分配的内存字节数。
3、 realloc()函数分配第⼆个参数指定的内存量,并把第⼀个参数指针指向的之前分配的内容复制到新配的内存中,且复制的内容长度等于新旧内存区域中较⼩的那⼀个。即新内存⼤于原内存,则原内存所有内容复制到新内存,如果新内存⼩于原内存,只复制长度等于新内存空间的内容。
4、realloc()函数的第⼀个参数若为空指针,相当于分配第⼆个参数指定的新内存空间,此时等价于malloc()、calloc()或realloc()函数。
5、如果是将分配的内存扩⼤,则有以下3种情况:
如果当前内存段后⾯有需要的内存空间,则直接扩展这段内存空间,realloc()将返回原指针。
如果当前内存段后⾯的空闲字节不够,那么就使⽤堆中的第⼀个能够满⾜这⼀要求的内存块,将⽬前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存块位置。
如果申请失败,将返回NULL,此时,原来的指针仍然有效。
⼆、注意事项
1、第⼀个参数要么是空指针,要么是指向以前分配的内存。如果不指向以前分配的内存或指向已释放的内存,结果就是不确定的。
2、如果调⽤成功,不管当前内存段后⾯的空闲空间是否满⾜要求,都会释放掉原来的指针,重新返回⼀个指针,虽然返回的指针有可能和原来的指针⼀样,即不能再次释放掉原来的指针。
今天就在释放原指针(即realloc()函数的第⼀个参数)这个地⽅犯了⼀个错误。下⾯是测试程序。测试程序的功能⾮常简单:实现在⼀个按升序排序的数组中查x应插⼊的位置,将x插⼊数组中,使数组元素仍按升序排列。
1 #include<stdio.h>
2 #include<stdlib.h>
3int main()
4 {
5int n = 0;
6int i = 0;
7int index = 0;
8int insert_data = 0;
9int *pNumber = NULL;
10int *pNewArray = NULL;
11    printf("Input array size:\n");
12    scanf("%d", &n);
13    pNumber = (int*)calloc(n, sizeof(int));
14if(pNumber == NULL)
15    {
16        printf("Not enough memory\n");
17        exit(0);
18    }
19//输⼊插⼊前已按升序排序的数组元素提⽰信息
20    printf("Input array:\n");
21for(i = 0; i < n; i++)
22    {
23        scanf("%d", pNumber+i);
24    }
25//输⼊待插⼊的元素x提⽰信息:
26    printf("Input x:\n");
27    scanf("%d", &insert_data);
28//确定待插⼊位置的索引值
29for(i = 0; i < n; i++)
30    {
31if(insert_data < *(pNumber+i))
32        {
33            index = i;
34break;
35        }
36    }
37//⽤realloc()新分配⼀块内存,⽤于存储原数组和新插⼊的值
38    pNewArray = (int*)realloc(pNumber, (n+1)*sizeof(int));
39if(pNewArray == NULL)
40    {
41        printf("Not enough memory\n");
42        exit(0);
43    }
44//free(pNumber);
45//输出新分配的内存空间的值,查看是否实现了复制
46for(i = 0; i < n+1; i++)
47    {
48        printf("%4d", pNewArray[i]);
49    }
50    printf("\n");
return在c语言中是什么意思51//待插⼊位置及后⾯的所有数据依次向后移1位
52for(i = n; i  > index; i--)
53    {
54        *(pNewArray+i) = pNewArray[i-1];
55    }
56    *(pNewArray + index) = insert_data;
57    printf("After insert %d:\n", insert_data);
58for(i = 0; i < n+1; i++)
59    {
60        printf("%4d", *(pNewArray+i));
61    }
62free(pNewArray);
63return0;
64 }
注意代码44⾏出,如果注释掉,则结果正确。如果不注释掉则错误。说明上⾯所述的注意事项中的第2条是正确的。下⾯是测试⽤例及结果。
左侧图⽚为注释掉代码44⾏的正确结果,右侧图⽚为未注释掉44⾏代码的错误结果。
之前⼀直觉得这个地⽅没有什么,没想到今天写程序时候在这个地⽅掉坑⾥⾯了。越是这种不注意的⼩地⽅越容易犯错。引以为戒。