1.structhack
Have you ever seen a struct definition like this
struct pack{
unsigned short count;
unsigned long id;
unsigned char data[1];
};
从前我喜欢申请一统一的buffer,在struct定义一指针,
进而实现边长数据的携带,譬如
struct comm{
unsigned short count;
unsigned long id;
unsigned char *data;
};
/*code start here*/
void init()
{
char *buff, *c;
c = buff = malloc(MAX_SIZE);
return;
}
void add()
{
struct comm *s;
s = malloc(sizeof(*s));
s->data = c;
c += DATA_SiZE;
return;
}
以上方法最大的弊病是涉及到buffer的管理,当申请释放频繁时,
不多久buffer就是一片狼藉了。
于是有了structhack,把以上问题转嫁给现存的完善的堆机制处理。
其基本流程如下
struct hack{
unsigned short count;
unsigned long id;
unsigned char data[1];
}
struct add()
{
struct hack * h;
h = malloc(sizeof(*h) + DATA_SIZE - 0x01);
memcpy(h->data, data, DATA_SIZE);
/* Now, You are available to handle h->data as a actual array with DATA_SIZE elements */
}
很明显,这种机制下边长数据的申请是释放都交由管理,且代码操作依然简单明了,完全等同于一个数组。
Futher Reading:[http://c-faq.com/struct/structhack.html]
2.Should you cast when malloc()?
char *str;
str = (char *)malloc(strlen(STRING) + 1);
Is this right? I do not think so.
很多人喜欢这么写,包括我自己;但是此般casting会隐瞒可能的BUG。
譬如当忘记引用stdlib.h时。
要知道对于一个未申明的函数,ANSI C标准中定义的操作是“认为其含有一个隐式的extern申明“。
也就是说,在没有包含stdlib.h的情况下,编译器会自动定义其为extern int malloc()。
问题就在于此,实际上malloc()的原型是void *malloc(),且.lib中的binary的压栈出栈代码亦是按
照该原型编译。一个int被赋值到char *,且如果强制类型转化操作存在,编译过程不会有任何警告。
这里有一篇相关文章[http://www.cpax.org.uk/prg/writings/casting.php],其观点认为在绝大多数
情况下切勿使用强制类型转换-于排错无益、对可读性也改善甚微。

