#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
static void show_pointer(void *p, char *descr) {
// printf("Pointer for %s at %p\n", descr, p);
printf("%s\t%p\t%lu\n", descr, p, (unsigned long) p);
}
char big_array[1L<<24]; /* 16 MB */
//char huge_array[1L<<31]; /* 2 GB */
char huge_array[1L<<30];/* 1 GB */
int global = 0;
int useless() { return 0; }
int main ()
{
void *p1, *p2, *p3, *p4;
int local = 0;
p1 = malloc(1L << 28);
p2 = malloc(1L << 8);
//p3 = malloc(1L << 32);
p3 = malloc(1L << 16);
p4 = malloc(1L << 8);
show_pointer((void *) big_array, "big array");
show_pointer((void *) huge_array, "huge array");
show_pointer((void *) &local, "local");
show_pointer((void *) &global, "global");
show_pointer((void *) p1, "p1");
show_pointer((void *) p2, "p2");
show_pointer((void *) p3, "p3");
show_pointer((void *) p4, "p4");
show_pointer((void *) useless, "useless");
show_pointer((void *) exit, "exit");
show_pointer((void *) malloc, "malloc");
return 0;
}
#include <unistd.h>
符号常量
是POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型,例如read函数、write函数和getpid函数
unistd.h在unix中类似于window中的windows.h!
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
unistd.h含有的常量与函数:
ssize_t read(int, void *, size_t);
int unlink(const char *);
ssize_t write(int, const void *, size_t);
int usleep(useconds_t);
unsigned sleep(unsigned);
int access(const char *, int);
unsigned alarm(unsigned);
int chdir(const char *);
int chown(const char *, uid_t, gid_t);
int close(int);
size_t confstr(int, char *, size_t);
void _exit(int);
pid_t fork(void);
NULL // Null pointer
SEEK_CUR // Set file offset to current plus offset.
SEEK_END // Set file offset to EOF plus offset.
SEEK_SET // Set file offset to offset.
static void show_pointer(void *p, char *descr)
char big_array[1L<<24];
l表示的是关键字long,数字后面加L表示的都是长整型量,数组大小为:1*2^24=16MB
p1 = malloc(1L << 28);
可用的堆内存块以“可用堆内存链表”的形式存在。malloc()进行动态分配的特点:
-
malloc()根据用户所需分配内存的大小n (bytes)在“堆链表”(见未使用过得堆内存)里搜索。直到搜索到一个大于等于n字节的堆内存块为止。如果此堆内存块的大小刚好为n,则直接将首地址返回给用户;如果此内存块的大小大于n,则将此块堆内存分裂,将大于n部分的堆内存留在可用堆内存中,以“堆链表”的形式和其它未分配的堆内存发生联系。
-
如果整个堆链表所代表的堆内存块都没有大于等于n的堆内存块,系统将给“堆链表”链接一个更大的区域供其使用。要是这一步也失败了,malloc()函数就返回NULL给用户。
malloc()函数分配内存成功则返回可用堆内存块的首地址,若分配失败则返回空。在使用malloc()后一定要判断堆内存是否成功。若对内存分配未成功使用指针操作内存也会使程序出现异常。动态分配内存时要采取以下结构:
char *pL =NULL;
……
pL = (char *)malloc( sizeof(char) * size);
if(pL)
{
…
}
分配成功后,得到的堆内存首地址一定要保存,不然后来无法释放堆内存而造成内存泄露。而且不可使用未初始化的pL指向的内存块。
此程序是要输出16MB、1GB在内存中的位置和存储的内容以及useless/exit/malloc等所在的地址和内容。