长度为0的数组

长度为0的数组——C语言的非标准用法之一 

在标准C和C++中,长度为0的数组是被禁止使用的。不过在GNU C中,存在一个非常奇怪的用法,那就是长度为0的数组,比如Array[0];很多人可能觉得不可思议,长度为0的数组是没有什么意义的,不过在这儿,它表示的完全是另外的一层意思,这个特性是不可移植的,所以,如果你致力于编写可移植,或者是稍稍需要跨平台的代码,这些Trick最好还是收起来的好。

在GNU的指南中,它是如此写道:

struct line {
int length;
char contents[0];
};

//...ommit code here

{
struct line *thisline
   = (struct line *) malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
}

这个用法主要用于变长Buffer,struct line的大小为4,结构体中的contents[0]不占用任何空间,甚至是一个指针的空间都不占,contents在这儿只是表示一个常量指针,这个特性是用编译器来实现的,即在使用thisline->contents的时候,这个指针就是表示分配内存地址中的某块buffer,比如malloc (sizeof (struct line) + this_length)返回的是0x8f00a40,thisline->contents指向的位置就是(0x8f00a40 + sizeof(struct line)),而这儿sizeof(struct line)仅仅是一个int的四字节。

对于这个用法,我们定义的结构体指针可以指向任意长度的内存buffer,这个技巧在变长buffer中使用起来相当方便。可能有朋友说,为什么不把最后的contents直接定义为一个指针呢?这儿的差别是这样的,如果定义为一个指针,它需要占用4Bytes,并且在申请好内存后必须人为赋地址才可以。如果使用这个用法,这个常量指针不占用空间,并且无需赋值。

但是,方便并不是绝对的,在释放分配的内存的时候,由于函数free会认为*thisline 只是指向一个4字节的指针,即只会释放length的空间,而对于后面占据大头的buffer却视而不见,这个就需要人为干预;而对于后面的声明指针的方式,则可以直接用Free(thisline->contents)的方式释放掉分配的内存。

ASSERT:除非必要,不要轻易使用这个功能,GNU C下可以编译通过,所以你在使用vc++,那就不用尝试了,编译都无法通过。

 

---------------------------------------------------------------------------------------------------------------------------

今天无意以为博友翻到我这篇老帖子,这也是当时我学习转载的,结果没加上转载。。。

我很多帖子都是转载,都是当时看看没求甚解,现在还是老样子,我计划看看这部分源码,加深一下,要不被找错多惭愧,先贴一段老外的话:

Without going thru how malloc works, Linux uses a version of Doug Lea's malloc program. When it allocates memory it uses two longs, and they muist live right next to each other for free to work. The first long is the length of the memory block allocated, the second is a pointer to the start of the block. The second one is the pointer that malloc returns.

顺手找到Doug Lea这个可爱的老头大师的文章:

http://blog.csdn.net/vincent_smz/article/details/6338417

 

后续的,我利用周末再看。

-----------------------------------------------------------------------------------------------------------------------------

在读帖子的时候,我对我之前的两个评论收回,还是理解不够深,free必须释放malloc分配的内存,如果free随意释放的话,会导致malloc管理的内存链出现问题:

If you inadvertantly swap the second one (the pointer ) with another pointer - ie., one that does not live nextdoor to the correct length value, free corrupts the blocks of heap memory that malloc handles. This causes all sorts of problems - free segfaulting, heap memory being incorrectly overwriteen, other segfaults.

This is what you have. Some other unix systems base memory allocation on where the pointer is "aimed" not where the pointer "lives in memory".

 

上述英文来自:

http://www.linuxquestions.org/questions/programming-9/free-does-not-clear-memory-space-in-linux-413123/

posted @ 2010-01-12 21:12  规格严格-功夫到家  阅读(2944)  评论(3编辑  收藏  举报