|
|
用户名:demonstrate 笔名:demonstrate 地区: 中国-上海 行业:其他 |
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
照片的链接来源于 http://demonstrate.photo.163.com/,如果你打不开有些图片,请右键点击该图片位置选择查看图片(View Image)。另外,这是我现在用的 GPG 公钥。
西江月 * 黄寅晓
- 作者: demonstrate 2007年02月22日, 星期四 22:24 回复(6) | 引用(1) 加入博采
望月怀远
- 作者: demonstrate 2006年11月25日, 星期六 17:23 回复(0) | 引用(1) 加入博采
GNU C library 笔记(2)
In GNU C, the size of the automatic storage can be an expression that
varies. In other C implementations, it must be a constant.
void * malloc (size_t size)分配到的内存没有初始化(calloc 会做清零,clear allocate),此可以用 memset 来
int mcheck (void (*abortfn) (enum mcheck_status status))来检查分配内存的一致性,调用在 malloc 之前。
enum mcheck_status mprobe (void *pointer)为特定的一块内存做检查。这都是 GNU extension。(mcheck.h)
void *function (size_t size, const void *caller)其中 caller 是调用 malloc 返回值的接受者(一个指针的地址)。另外有 __malloc_initialize_hook
struct mallinfo mallinfo (void)获得。
void mtrace (void)及其反作用
void muntrace (void)这时会依赖于一个环境变量 MALLOC_TRACE 所指的文件,把一些信息记录在该文件中
#include <stdio.h>很简单的程序,其中 q 没有被释放。我们设置了环境变量后并且 touch 出该文件
#include <stdlib.h>
#include <mcheck.h>
int
main( int argc, char *argv[] )
{
int *p, *q ;
#ifdef DEBUGGING
mtrace( ) ;
#endif
p = malloc( sizeof( int ) ) ;
q = malloc( sizeof( int ) ) ;
printf( "p = %p\nq = %p\n", p, q ) ;
*p = 1 ;
*q = 2 ;
free( p ) ;
return 0 ;
}
p = 0x98c0378该文件内容如下
q = 0x98c0388
= Start可以知道带有 + 的表示 malloc 了内存,而 - 表示释放,后面的 0x4 是分配的内存大小
@ ./test30:[0x8048446] + 0x98c0378 0x4
@ ./test30:[0x8048455] + 0x98c0388 0x4
@ ./test30:[0x804848f] - 0x98c0378
08048424 <main>:可见是调用函数开始地方的地址。下面使用 mtrace 命令行工具进行分析,其基本调用方式为
...
8048441: e8 d2 fe ff ff call 8048318
8048446: 89 45 f4 mov %eax,0xfffffff4(%ebp)
8048449: c7 04 24 04 00 00 00 movl {fckeditor}x4,(%esp)
8048450: e8 c3 fe ff ff call 8048318 <malloc@plt>;
8048455: 89 45 f8 mov %eax,0xfffffff8(%ebp)
8048458: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
804845b: 89 44 24 08 mov %eax,0x8(%esp)
804845f: 8b 45 f4 mov 0xfffffff4(%ebp),%eax
8048462: 89 44 24 04 mov %eax,0x4(%esp)
8048466: c7 04 24 54 85 04 08 movl {fckeditor}x8048554,(%esp)
804846d: e8 c6 fe ff ff call 8048338 <printf@plt>
8048472: 8b 45 f4 mov 0xfffffff4(%ebp),%eax
8048475: c7 00 01 00 00 00 movl {fckeditor}x1,(%eax)
static struct obstack myobstack;当然,malloc 一个也行的。不过首先应该告诉编译器用什么分配 chunk -.-
obstack_init (&myobstack);
#define obstack_chunk_alloc malloc分配的 chunk 大小是用下面的 macro 决定的
#define obstack_chunk_free free
int obstack_chunk_size (struct obstack *obstack-ptr)调用方式如下:
obstack_chunk_size (obstack_ptr) = new-chunk-size;如果 trunk 分配失败,则会调用 obstack_alloc_failed_handler 对应的函数指针。
void * obstack_alloc (struct obstack *obstack-ptr, int size)然后手动 memcpy 好了... 这样麻烦,因此有个
void * obstack_copy (struct obstack *obstack-ptr, void *address, int size)减少工作量,对于字符串呢还有更简单的
void * obstack_copy0 (struct obstack *obstack-ptr, void *address, int size)这样最后的 0x0 会自动被添加。如果想释放,可以调用
void obstack_free (struct obstack *obstack-ptr, void *object)这时 obstack 中在此 object 之后添加的都会被释放掉(这才是 stack 嘛~)注意,如果 object == NULL,此时
void obstack_blank (struct obstack *obstack-ptr, int size)分配空间,但不初始化,
void obstack_grow (struct obstack *obstack-ptr, void *data, int size)让这部分空间变大(size 可以为负,那就是变小,但不会缩过头 @@),为了方便字符串等等数据类型
void obstack_grow0 (struct obstack *obstack-ptr, void *data, int size)grow 完了最后要 finish 一下
void obstack_1grow (struct obstack *obstack-ptr, char c)
void obstack_ptr_grow (struct obstack *obstack-ptr, void *data)
void obstack_int_grow (struct obstack *obstack-ptr, int data)
void * obstack_finish (struct obstack *obstack-ptr)可以在 finish 之前测一下这个家伙有多大
int obstack_object_size (struct obstack *obstack-ptr)不过因为这样做每 grow 一点都会检查是否需要分配新的 chunk 因此较慢,当有连续的
void obstack_1grow_fast (struct obstack *obstack-ptr, char c)为了方便之前检查 chunk 剩余空间是否够用可以用
void obstack_blank_fast (struct obstack *obstack-ptr, int size)
int obstack_room (struct obstack *obstack-ptr)
void * obstack_base (struct obstack *obstack-ptr)返回下一个 object 的地址(栈顶),如果有 growing object 则是该 object 地址。
int obstack_alignment_mask (struct obstack *obstack-ptr)使用类似设置 chunk size。
int这样一个好处在于 longjmp() 时不需要再手工释放这部分内存。并且使用 alloca 分配的内存是
open2 (char *str1, char *str2, int flags, int mode)
{
char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
stpcpy (stpcpy (name, str1), str2);
return open (name, flags, mode);
}
int open2 (char *str1, char *str2, int flags, int mode)两种方式并不相同,后者可能仍然在栈内分配的内存,因此作用域结束即释放,而前者在程序结束
{
char name[strlen (str1) + strlen (str2) + 1];
stpcpy (stpcpy (name, str1), str2);
return open (name, flags, mode);
}
int brk (void *addr)名字由来是原来进程里面 data segment 和 stack 对着干,一个从上向下长,一个从下向上长
int sbrk (ptrdiff_t delta)
int mlock (const void *addr, size_t len)这些是 POSIX.1b 的标准。
int munlock (const void *addr, size_t len)
int mlockall (int flags)
int munlockall (void)
- 作者: demonstrate 2006年11月25日, 星期六 17:16 回复(0) | 引用(1) 加入博采
感遇(其一)
- 作者: demonstrate 2006年11月18日, 星期六 22:11 回复(0) | 引用(1) 加入博采
GNU C library 笔记(1)
#define _GNU_SOURCE该例子给出了如何使用非 ISO C 的 program_invocation_(short_)name 变量(程序名带或者不带路径)的例子。使用 _REENTRANT 和 _THREAD_SAFE 时保证使用对应的函数。
#include <stdio.h>
#include <errno.h>
int
main( int argc, char *argv[] )
{
printf( "%s\n%s\n%s\n", argv[0],
program_invocation_short_name,
program_invocation_name ) ;
return 0 ;
}
- 作者: demonstrate 2006年11月12日, 星期日 16:04 回复(0) | 引用(1) 加入博采
长安古意
- 作者: demonstrate 2006年11月12日, 星期日 15:59 回复(0) | 引用(1) 加入博采
AUCTeX 使用手记
- 作者: demonstrate 2006年07月26日, 星期三 10:56 回复(2) | 引用(1) 加入博采
研究生一年回顾
- 作者: demonstrate 2006年07月2日, 星期日 21:25 回复(2) | 引用(1) 加入博采
六月最后一天的留恋
- 作者: demonstrate 2006年06月30日, 星期五 01:49 回复(0) | 引用(1) 加入博采
明月何皎皎
- 作者: demonstrate 2006年06月29日, 星期四 01:04 回复(0) | 引用(4) 加入博采
客从远方来
- 作者: demonstrate 2006年06月28日, 星期三 02:40 回复(0) | 引用(1) 加入博采
孟冬寒气至
- 作者: demonstrate 2006年06月27日, 星期二 01:25 回复(0) | 引用(1) 加入博采
凛凛岁云暮
- 作者: demonstrate 2006年06月26日, 星期一 01:36 回复(0) | 引用(1) 加入博采
生年不满百
- 作者: demonstrate 2006年06月25日, 星期日 00:29 回复(0) | 引用(61) 加入博采