qey

Atitude is Everything.-- 关注C/C++,关注Linux(Unix) ,关注网络。 Better Late Than Never.
随笔 - 4, 文章 - 13, 评论 - 7, 引用 - 0
数据加载中……

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 


posted on 2009-10-09 16:54 无声无色 阅读(753) 评论(0)  编辑 收藏 引用 所属分类: 语言基础


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理