C语言动态存储分配

C语言动态存储分配

在程序运行时,分配“堆区”的存储空间。
为了动态地分配存储空间,需要调用三种内存分配函数的一种,这些函数都声明在<stdlib.h>头文件中。

  • malloc 函数——分配内存块,但是不对内存块进行初始化。
  • calloc 函数——分配内存块,并且对内存块进行清零。
  • realloc 函数——调整先前分配的内存块大小。
    在这三种函数中,malloc函数是最常用的一种。因为 malloc 函数不需要对分配的内存块进行清零,所以它比 calloc 函数更高效。
    当为申请内存块而调用内存分配函数时,函数会返回 void *类型的值。
    指向任意类型对象的指针能隐式转换成指向 void 的指针。

空指针

当调用内存分配函数时,如果找不到满足我们需要的足够大的内存块,函数会返回空指针(null pointer)。
空指针是不指向任何地方的指针,这是一个区别于所有有效指针的特殊值。
C语言中,空指针用名为 NULL 的宏来表示。

malloc 函数

函数原型:
void * malloc(size_t size);
malloc 函数分配 size 个字节的内存块,并且返回指向该内存块的指针。
注意,size 的类型是 size_t,这是在C语言库中定义的无符号整数类型。

/* 分配一个整型数的存储空间 */
int *p = malloc(sizeof(int));
/* 连续分配N个整型数的存储空间,即数组 */
int *p = malloc(N * sizeof(int));  
/* 连续分配N+1个字符型的存储空间,即字符串 */
char *c = malloc((N+1)*sizeof(char));  //加上结束符
char *c = malloc( (strlen(str)+1)*sizeof(char) );

calloc 函数

函数原型:
void * calloc(size_t nmenb,size_t size);
calloc 函数为 nmemb 个元素的数组分配内存空间,其中每个元素的长度都是 size 个字节。
在分配了内存之后,calloc 函数会通过把所有位设置为 0 的方式进行初始化。
例如, calloc 函数调用:

/*为N个整数的数组分配存储空间,并为所有整数初始化为0*/
int *p = calloc(N,sizeof(int));

realloc 函数

函数原型:
void * realloc(void *ptr,size_t size);
当调用 realloc 函数时,ptr 必须指向先前通过 malloc、calloc或 realloc 的调用获得的内存块。size 表示内存块的新尺寸,新尺寸可能会大于或小于原有尺寸。
C标准列出了几条关于 realloc 函数的规则:

  • 当扩展内存块时,realloc 函数不会对添加进内存块的字节进行初始化。
  • 如果 realloc 函数不能按要求扩大内存块,那么它会返回空指针,并且在原有的内存块中的数据不会发生改变。
  • 如果 realloc 函数被调用时以空指针作为第一个实际参数,那么它的行为就将像 malloc 函数一样。
  • 如果 realloc 函数被调用时以0作为第二个实际参数,那么它会释放掉内存块。
    在要求减少内存块大小时,realloc 函数应该在原先的内存块上直接进行缩减,而不需要移动存储在内存块中的数据。
    同理,扩大内存块时也不应该对其进行移动。如果无法扩大内存块,realloc 函数会在别处分配新的内存块,然后把旧块中的内容复制到新块中。

free 函数

函数原型:
void free(void *ptr);
用于释放 ptr 指向的不再需要的内存块,将 malloc 函数或 calloc 函数返回的指针作为参数,传给 free 函数以释放内存。

关于动态地分配存储注意的问题

问题1:以下代码生成此警告,因为如果内存不足,则 malloc 调用可能会返回 NULL:

#include <stdlib.h>

void f()
{
  char *p = ( char * ) malloc( 10 );
  *p = '\0';
 free( p );
}

若要更正此警告,请检查指针以获取 NULL 值,如以下代码所示:

#include <stdlib.h>

void f( )
{
  char *p = ( char * )malloc ( 10 );
  if ( p != NULL )
  {
    *p = '\0';
    free( p );
  }
}

问题2:将返回值从 realloc 赋给 x。如果 realloc 失败并返回 null 指针,则不会释放指向 x 的原始内存:

#include <stdlib.h>
void f()
{
    char *x = (char *) malloc(10);
    if (x != NULL)
    {
        x = (char *) realloc(x, 512);
        free(x);
    }
}

若要解决此问题,可以创建一个临时变量来存储 realloc 的返回值。 此更改允许在失败时 realloc 安全地释放以前分配的内存:

#include <stdlib.h>

void f()
{
    char *x = (char *) malloc(10);
    if (x != NULL)
    {
        char *temp = (char *) realloc(x,512);
        if (temp != NULL)
        {
            x = temp;
        }
        free(x);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

往昔的恒纳兰那

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值