zoukankan      html  css  js  c++  java
  • 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:
    ");
    12     scanf("%d", &n);
    13     pNumber = (int*)calloc(n, sizeof(int));
    14     if(pNumber == NULL)
    15     {
    16         printf("Not enough memory
    ");
    17         exit(0);
    18     }
    19     //输入插入前已按升序排序的数组元素提示信息
    20     printf("Input array:
    ");
    21     for(i = 0; i < n; i++)
    22     {
    23         scanf("%d", pNumber+i);
    24     }
    25     //输入待插入的元素x提示信息:
    26     printf("Input x:
    ");
    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
    ");
    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("
    ");
    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:
    ", 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行代码的错误结果。

    之前一直觉得这个地方没有什么,没想到今天写程序时候在这个地方掉坑里面了。越是这种不注意的小地方越容易犯错。引以为戒。

           

  • 相关阅读:
    Xftp6 和 Xshell 6 下载与安装使用
    Oracle 11 安装教程(桌面类)
    Oracle 11 安装 提示环境不满足最低要求解决方案
    FICO年终完全手册
    SAP月结操作讲解
    ABAP-FI常用BAPI
    FB01与F-02的区别(转载)
    SAP应用创新-维护控制表、视图统一路径
    FI 业务
    SAP 财务模块 FI-TV 差旅管理
  • 原文地址:https://www.cnblogs.com/guojingdeyuan/p/9033411.html
Copyright © 2011-2022 走看看