Archive for 一月, 2010

C的泛型库khash

Posted on 一月 30th, 2010 in 备忘 | 5 Comments »

写小东西需要用到哈希表这样的数据结构时候才后悔没用C++,最起码还有stl能用来着。虽说C也能搞泛型,不过宏实现的泛型…真的好恐怖。

tinyrb用了khash做哈希表,据作者说已经是一个稳定的实现了。

khash.h的内容:
http://attractivechaos.awardspace.com/khash.h.html

大体可以这么用:

#include "stdio.h"
#include "khash.h"
KHASH_MAP_INIT_STR(str, int) //以“str”这名字初始化一个类型的map,键类型为字符串,值类型为int
int main() {
    int ret, is_missing;
    khiter_t k; //khash的索引器,好像就是个int
    khash_t(str) *h = kh_init(str); //str只是个名字,初始化
    k = kh_put(str, h, "test", &ret); //“test”即键,ret判定操作是否成功,返回k为索引器
 
    if (!ret) kh_del(str, h, k); //如果h中已经存在了这个键,就删除之
    kh_value(h, k) = 10; //设置键“test”对应的值(10)
 
    printf("%d\n", kh_val(h,k)); //kh_val(h,k)即10
 
    k = kh_get(str, h, "test"); //获得“test”对应的索引器k
    printf("%d\n", kh_val(h,k)); //得10
 
    kh_destroy(str, h);
    return 0;
}

终究不如模板来的自然,呵呵~不过也不错了。

折腾grub小记

Posted on 一月 26th, 2010 in 备忘 | No Comments »

蛋疼用PQMagic改了下/swap分区的大小,重启发现mbr没了。

拿手机google下之后,找了张windows me的光盘(初一时候买的盘还能用…orz)引导进入dos,fdisk /mbr,windows原地满血复活…满血,是的,windows又把mbr占了…

接着装个wingrub,折腾半天找回了原先的menu.lst,重启,接着是:

Error 2: Bad file or directory type

而且在grub命令下无法列出ext3分区的文件,当时冷汗天杀的PQMagic没把我盘格了吧…回头想下,感情这个wingrub好像不认ext3…

下载个live-CD,进去发现可以读那个分区。apt-get一个grub,进入命令行之后:

root (hd0, 4)
setup (hd0)

提示成功。重启,原先的grub回来了…

typedef unsigned long VALUE;

Posted on 一月 19th, 2010 in 笔记 | 8 Comments »

因为swdpress.cn的死掉严重打击积极性,好久没更新了。此文纯凑数。

ruby中除了Fixnum,其余所有类型的值都是引用传递。读《ruby hacking guide》时看到如下的定义:

typedef unsigned long VALUE;

同lua那union+tag不一样,ruby中所有类型的值都存放在一个VALUE中,而没有tag指明其类型。如果是Fixnum,就把数值直接放在VALUE里;如果是其它类型,则存放其地址(unsigned long和C中指针类型的长度一致)。不过万一作为Fixnum的VALUE指向的地址与其他对象有重叠怎么办?它又怎么区别数值和地址呢?

这用到了一点tricks,C的struct在内存中都是以4字节对齐,因此ruby中所有对象的地址都偶数。在表示Fixnum时,ruby就将C的int值左移一位再加一,使其看起来总是个奇数,这样就不会与ruby的其它对象有重叠。

 123  #define INT2FIX(i) ((VALUE)(((long)(i))<<1 | FIXNUM_FLAG))
 122  #define FIXNUM_FLAG 0x01
(ruby.h)

判断一个VALUE是Fixnum还是地址,只需判断VALUE是奇数还是偶数就行了。

表示true,false和nil是这样:

 164  #define Qfalse 0        /* Ruby's false */
 165  #define Qtrue  2        /* Ruby's true */
 166  #define Qnil   4        /* Ruby's nil */
(ruby.h)

都是偶数。像刚才说的,它们不会被当作是地址了么?这就用到了另一个trick:进程虚拟地址空间的前一部分都是不可访问的。因而0,2,4的地址上不会存在ruby对象。

PS: 感谢FX大大提醒,这套方法有个标准的名字叫做“tagged pointer” :)

搬家,接着折腾

Posted on 一月 9th, 2010 in 杂碎 | 7 Comments »

从胡戈戈同学那里买来的合租。有点杯具,在域名开通的时候想到一个更喜欢的,无所谓了,以后一年一换。

新地址:http://fleurer-lee.com/
麻烦各位有友链的同学了 :<

各种杯具又集体出现…我很能折腾…姑且看能折腾多久吧。