alayi

程序人生用音乐来点缀

博客园 首页 联系 订阅 管理
3 内存管理

程序内存 地址空间 可执行文件节
代码 代码 代码
初始化数据 数据 数据
BSS 数据 BSS
数据

                                                                                                            可执行程序段和他们的位置
内存管理的几个函数

void *calloc(size_t nmemb, size_t size);       //分配后用零来填充
void *malloc(size_t size);                            //分配原始内存
void free(void *ptr);                                   //释放内存
void realloc(void *ptr, size_t size);              //改变已分配内存的大小


struct coord{                                   //3D坐标
    int x,y,z;
*coordinates;
unsigned 
int count;                             //我们需要多少数量
size_t amount;                                  //要分配的内存总量
/*
..以某种方式决定数量..*/
amount 
= count * sizeof(struct coord);          //要分配多少字节
coordinates = (struct coord *)malloc(amount);   //得到地址空间
if(coordinates == NULL){
/*错误报告,重新获得或者放弃*/
}
/*..使用coordinates..*/

步骤
(1)声明一个适当类型的指针,准备指向分配好的内存。
(2)计算要分配的内存的字节数。用单个目标的字节大小乘以需要目标个数所得值就是需要的字节数。单个目标大小是通过C的sizeof算子提取出来的。
(3)在调用malloc()分配存储空间之后,将该函数的返回值赋给另一个指针变量。将malloc()返回值的类型转换到要赋值的变量的类型是个好习惯
(4)检查返回值。



注意
malloc()返回的内存是
"没有"初始化的。应马上用有效数据或至少是用零来初始化这块内存。

推荐:
some_type *pointer;
pointer = malloc(count * sizeof(*pointer));
这个方法保证了malloc()会分配正确数量的内存,而不用考虑pointer的声明。如果pointer的类型后来变了,sizeof算子自动确保要分配的字节数仍然正确


关于free()的几个要注意的地方

访问释放掉的内存
这么做不管从可靠性和可移植性等各方面都是愚蠢的。所以最好在释放内存后把悬挂指针设置为NULL
free(pointer);
pointer 
= NULL; //It's not necessarily, but a good idea

两次释放相同指针

缓存过多和缓存过少

释放内存失败


GLIBC 中读取整个行:getline()和getdelim()
#include <stdio.h>
#include <sys/types.h>
   //为了使用ssize_t  ssize_t 是"有符号的size_t"
#define _GNU_SOURCE 1

ssize_t getline(
char **lineptr, size_t *n, FILE *stream);
ssize_t getdelim(
char **lineptr, size_t *n, int delim, FILE *stream);

这两个函数都可以为你管理动态存储空间,确保包含输入行的缓冲区总是足以存下整个输入行,他们的区别在于getline直到遇到换行符才停止读取,而getdelim使用的是用户提供的分界符。

char **lineptr:
指向char*的指针,它保存了动态分配的缓冲区的地址。如果希望getline()完成所有的工作,那么可以设置成NULL。否则,它应该指向前面用malloc()分配的存储空间。

size_t *n
指示缓冲区的大小,如果分配自己的缓冲区,*n应该包含缓冲区的大小。如果它们改变了缓冲区的话,两个函数都会根据新的缓冲区大小更新*n。

FILE *stream
获取输入字符的地方。

函数遇到文件结束标志(end-of-file)或者错误的时候返回-1。函数lineptr参数会保存终止的换行符或者分界符(如果有的话),以及终止的零字节。getline()用起来很容易。



#include <stdio.h>
#include <sys/types.h>
#define _GNU_SOURCE 1

/*..main --- 读取行并显示出来,直到EOF..*/
int main(void)
{
  
char *line = NULL;
  size_t size 
= 0;
  ssize_t ret;

  
while ((ret = getline(&line, &size, stdin)) != -1)
    printf(
"(%lu) %s", size, line);

  
return 0;
}

字符串拷贝 strdup()
#include <string.h>
char *strdup(const char *str);
错误返回NULL;正确返回值就是指向动态分配的存储空间的指针,这个存储空间中存放有str的拷贝。当不需要返回值的时候就应该用free()把它释放掉。











posted on 2007-11-05 10:27  alayi  阅读(248)  评论(0)    收藏  举报