C语言动态内存分配:(二)malloc/calloc/realloc/aligned_malloc

1、函数原型

(1)malloc用来分配size字节的内存

void *malloc( 
   size_t size 
);

(2)calloc分配n个size大小的连续的空间

void *calloc( 
   size_t num,
   size_t size 
);

(3)realloc用于修改一个已经分配的内存块的大小

void *realloc( 
   void* memblock, 
   size_t size 
);

(4)_aligned_malloc:在一个特定的对齐边界分配内存(VS中)

void * _aligned_malloc(
    size_t size, 
    size_t alignment
);
 

2、函数说明:

(1)返回值:

         1)malloc调用成功时,返回分配的内存块的首地址。失败时,返回NULL。size为0时,返回的指针不是NULL;但是除了free,别的地方不要使用这个指针。

         2)calloc调用成功时,返回分配的数组的首地址。失败时,返回NULL。

         3)realloc调用成功:size不为0时,返回重新分配的内存块的首地址;size为0时,返回NULL(原来的内存被释放掉了),有些系统实现返回的指针不是NULL;但是除了free,别的地方不要使用这个指针。。

              返回NULL:当没有足够的空间可供扩展的时候。此时,原内存空间的大小维持不变。

 (2)函数实现

    1)链接:malloc/free的实现及malloc实际分配的内存

    2)如果size小于原来的内存大小:则只有size大小的数据会被保存,原来内存块尾部的部分会被删掉。会发生数据丢失,慎重使用。

          如果size大于原来的内存大小:假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址; 假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,realloc返回新内存的地址(新内存并不会初始化)

3、联系与区别

(1)calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。

(2)如果realloc的memblock为NULL,则realloc()和malloc()类似。分配一个size的内存块,返回一个指向该内存块的指针。
         如果size大小为0,那么释放memblock指向的内存,并返回NULL。

4、注意事项

   链接:动态内存分配注意事项

(1)对于realloc不要将返回结果再赋值给原指针,即ptr=realloc(ptr,new_size)是不建议使用的,因为如果内存分配失败,ptr会变为NULL,如果之前没有将ptr所在地址赋给其他值的话,会发生无法访问旧内存空间的情况,所以建议使用temp=realloc(ptr,new_size)。

(2)传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的,或者为NULL

(3)realloc的size小于原来的内存块大小时,会造成数据丢失。size大于原来的内存大小时,可能会重新分配内存,因此原来的指针ptr指向的旧内存会被free掉,因此不可以再使用ptr取原来内存中的数据,应该改用realloc返回的新指针。

(4)因为动态内存分配可能会失败,因此对每次返回的指针都进行检查确保它并非NULL非常重要。

(5)调用calloc()时,要确保参数相乘时不会超过类型大小而变为负数。(最好室友unsigned int或者size_t类型)

5、使用示例

(1)calloc

#include 
#include 
void main( void )
{
	int *buffer;
	buffer = (int *)calloc( 10, sizeof( int ) );
	if( buffer != NULL )
		for(int i=0;i<10;i++)
			printf( "%d",buffer[i] );
	else
		printf( "Can't allocate memory\n" );
	free( buffer );
}

(2)realloc

/* REALLOC.C: This program allocates a block of memory for
 * buffer and then uses _msize to display the size of that
 * block. Next, it uses realloc to expand the amount of
 * memory used by buffer and then calls _msize again to
 * display the new amount of memory allocated to buffer.
 */

#include 
#include 
#include 

void main( void )
{
   long *buffer;
   size_t size;

   if( (buffer = (long *)malloc( 1000 * sizeof( long ) )) == NULL )
      exit( 1 );

   size = _msize( buffer );
   printf( "Size of block after malloc of 1000 longs: %u\n", size );

   /* Reallocate and show new size: */
   if( (buffer = (long*)realloc( buffer, size + (1000 * sizeof( long )) )) ==  NULL )
      exit( 1 );
   size = _msize( buffer );
   printf( "Size of block after realloc of 1000 more longs: %u\n", 
            size );

   free( buffer );
   exit( 0 );
}

结果:




参考文献:

1、MSDN

2、《C和C++安全编码》

你可能感兴趣的:(C,C++)