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>
 3 int main()
 4 {
 5     int n = 0;
 6     int i = 0;
 7     int index = 0;
 8     int insert_data = 0;
 9     int *pNumber = NULL;
10     int *pNewArray = NULL;
11     printf("Input array size:\n");
12     scanf("%d", &n);
13     pNumber = (int*)calloc(n, sizeof(int));
14     if(pNumber == NULL)
15     {
16         printf("Not enough memory\n");
17         exit(0);
18     }
19     //輸入插入前已按升序排序的數組元素提示信息
20     printf("Input array:\n");
21     for(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     //確定待插入位置的索引值
29     for(i = 0; i < n; i++)
30     {
31         if(insert_data < *(pNumber+i))
32         {
33             index = i;
34             break;
35         }
36     }
37     //用realloc()新分配一塊內存,用於存儲原數組和新插入的值
38     pNewArray = (int*)realloc(pNumber, (n+1)*sizeof(int));
39     if(pNewArray == NULL)
40     {
41         printf("Not enough memory\n");
42         exit(0);
43     }
44     //free(pNumber); 
45     //輸出新分配的內存空間的值,查看是否實現了復制
46     for(i = 0; i < n+1; i++)
47     {
48         printf("%4d", pNewArray[i]);
49     }
50     printf("\n");
51     //待插入位置及后面的所有數據依次向后移1位
52     for(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);
58     for(i = 0; i < n+1; i++)
59     {
60         printf("%4d", *(pNewArray+i));
61     }
62     free(pNewArray);
63     return 0;
64 }

 

注意代碼44行出,如果注釋掉,則結果正確。如果不注釋掉則錯誤。說明上面所述的注意事項中的第2條是正確的。下面是測試用例及結果。

左側圖片為注釋掉代碼44行的正確結果,右側圖片為未注釋掉44行代碼的錯誤結果。

之前一直覺得這個地方沒有什么,沒想到今天寫程序時候在這個地方掉坑里面了。越是這種不注意的小地方越容易犯錯。引以為戒。

 

 

       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM