stdlib.h 中常用函数[1]内存分配和释放

stdlib.h 中常用函数[1]内存分配和释放


基本信息:// joen.hong#gmain.com
// 可任意转载,但请注明连接;
// 本文为巩固基础学习之用;
// 2009年10月09日
// 本文内容来源于C库头文件和Linux manual:
    在stdlib.h 中的几个重要内存管理函数为 calloc(), malloc(), free(), realloc();当然还有其他的函数,
这里不打算全部都列出来了。详细加深理解的话,还是要看手册和代码实现源文件。

一、内存分配和释放函数:


函数原型:void *calloc(size_t nmemb, size_t size);
功    能:calloc() 分配nmemb 个元素的数组空间,每个元素大小为size 个字节;返回分配内存的指针。
          所分配的内存设置为0;如果nmemb 或size 为0,返回NULL或是一个可被成功传送给free函数的唯一指针值。
返 回 值:返回指向新分配内存指针,这个内存指针合适地对齐任何类型变量。出错返回NULL。
          注意但nmemb 或size 为0时,成功也有可能返回NULL。
参考函数:sbrk(2);brk(2);mmap(2);alloca(3);

函数原型:void *malloc(size_t size);
功    能:malloc() 分配size 字节,返回指向分配到的内存的指针。内存不做清理。
          如果size 为0,malloc() 返回NULL或是一个可被成功传送给free函数的唯一指针值。
返 回 值:返回指向新分配内存指针,这个内存指针合适地对齐任何类型变量。出错返回NULL。

函数原型:void free(void *ptr);
功    能:释放ptr 指向的内存空间,ptr 必须是由之前的malloc(),calloc(),或realloc()
          调用返回的。否则,free(ptr) 之前已经被调用过,发生的行为是不确定的。
          如果ptr 为NULL,就什么也不做。
返 回 值:没有返回值。

函数原型:void *realloc(void *ptr, size_t size);
功    能:realloc() 用来将ptr 指向的内存块的大小改为size 字节。The contents will be unchanged the minimum of
          the old and new sizes;
          新分配的内存不会被初始化。 如果ptr 为NULL,那么调用就等同于malloc(size),size 为任意合适值;
          如果size 为0,并且ptr 又不是NULL,那么调用等同于 free(ptr)。除非ptr为空,否则ptr 必须是由之前的
          malloc(),calloc(),或realloc()调用返回的。如果ptr指向区域已经被移除,那么会发生free(ptr) 效果。
返 回 值:realloc() 返回指向新分配的内存指针,这个内存指针合适地对齐任何类型变量,可能ptr 指向不同;
          请求失败返回NULL。如果size 为0,返回NULL或是一个可被成功传送给free函数的唯一指针值。
          如果realloc() 失败,ptr 指向的初始内存块,保持不变,不被释放或移动。


二、函数基本应用:

1.二维动态数组分配练习:

 1  #include  < stdio.h >
 2  #include  < stdlib.h >
 3 
 4  int  main( int  argc,  char   * argv[])
 5  {
 6       int  i, j, n, m;
 7      scanf( " %d%d " & n,  & m);
 8       int    * array;
 9      printf( " row: %d, col: %d\n " , n, m);
10      
11       /*  malloc 分配一维数组当二维数组使用
12       * ,引用方式:如下(1)(2)
13        */
14      array  =  ( int   * )malloc(n  *  m  *   sizeof ( int ));
15       for  (i  =   0 ; i <  n; i ++
16           for (j  =   0 ; j <  m; j ++
17              scanf( " %d " , array  + * + j);        /* (1) */
18      
19      
20       for  (i  =   0 ; i <  n; i ++ ) {
21           for (j  =   0 ; j <  m; j ++ )
22              printf( " %d\t " , array[m  * + j]);       /* (2) */
23          printf( " \n " );
24      }
25 
26      free(array);
27       return   0 ;
28  }   
29

$ cat testdata.txt
5 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8

$ ./a.out < testdata.txt
row: 5, col: 8
1    2    3    4    5    6    7    8    
1    2    3    4    5    6    7    8    
1    2    3    4    5    6    7    8    
1    2    3    4    5    6    7    8    
1    2    3    4    5    6    7    8    

 1  #include  < stdio.h >
 2  #include  < stdlib.h >
 3 
 4  int  main( int  argc,  char   * argv[])
 5  {
 6       int  i, j, n, m;
 7      scanf( " %d%d " & n,  & m);
 8      printf( " row: %d, col: %d\n " , n, m);
 9      
10       /*  尝试类似一般二维数组引用的分配方法  */
11       int    ** array;
12      array  =  ( int   ** )malloc( sizeof ( int   * *  n);
13       for  (i  =   0 ; i  <  n; i ++ )
14          array[i]  =  ( int   * )malloc( sizeof ( int *  m);
15 
16       for  (i  =   0 ; i <  n; i ++ )
17           for (j  =   0 ; j <  m; j ++ )
18              scanf( " %d " & array[i][j]); 
19      
20       for  (i  =   0 ; i <  n; i ++ ) {
21           for (j  =   0 ; j <  m; j ++ )
22              printf( " %d\t " , array[i][j]); 
23          printf( " \n " );
24      }
25 
26       /*  释放内存比较麻烦, 注意顺序  */
27       for  (i  =   0 ; i  <  n; i ++ )
28          free(array[i]);
29      free(array);
30 
31       return   0 ;
32  }
33 

和引用和一般二维数组是一样的,只是二维数组在内存上是连续的。
而类似上面动态分配的二维数组,很可能在内存上并不连续,二进制代码中访问数据过程并不一样。

2.一种错误的应用方式:

 1  #include  < stdio.h >
 2  #include  < stdlib.h >
 3 
 4  int  main( int  argc,  char   * argv[])
 5  {
 6       int  a  = 5 , b  = 10 /* 测试用 */
 7       int  i, j, n, m;
 8      scanf( " %d%d " & n,  & m);
 9     
10       int    ** array;
11       int   * dest;
12      dest  =  ( int   * )malloc( sizeof ( int   * *  n);
13       /*  a,b,n,m,dest,array等的值可能已被修改,和变量在栈的分配顺序等有关  */
14      array  =   & dest;  /*   array必须是足够大的空间保存int*数组,但不是 */
15       for  (i  =   0 ; i  <  n; i ++ ) {
16          printf( " row: %d, col: %d\t " , n, m);
17          printf( " a: %d, b: %d\n " , a, b);
18          printf( " dest: 0x%x\t " , dest);
19          printf( " array: 0x%x\n\n " , array);
20          
21          array[i]  =  dest  +  n  *  i;
22      }
23 
24       for  (i  =   0 ; i <  n; i ++ )
25           for (j  =   0 ; j <  m; j ++ )
26              scanf( " %d " & array[i][j]); 
27      
28       for  (i  =   0 ; i <  n; i ++ ) {
29           for (j  =   0 ; j <  m; j ++ )
30              printf( " %d\t " , array[i][j]); 
31          printf( " \n " );
32      }
33 
34       // free(dest);
35       return   0 ;
36  }
37 


你可能感兴趣的:(stdlib.h 中常用函数[1]内存分配和释放)