`

长度为0的数组

 
阅读更多

转载自:http://www.cnblogs.com/diyunpeng/archive/2010/01/12/1645877.html

 

长度为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/

分享到:
评论

相关推荐

    matlab数组长度matlab数组长度

    matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度matlab数组长度...

    matlab求数组长度

    matlab求数组长度matlab求数组长度matlab求数组长度matlab求数组长度matlab求数组长度matlab求数组长度matlab求数组长度matlab求数组长度matlab求数组长度matlab求数组长度matlab求数组长度matlab求数组长度matlab求...

    不改变长度删除数组中的元素

    标题"不改变长度删除数组中的元素"所涉及的知识点,实际上是在探讨如何在保持数组长度不变的情况下,移除其中的特定元素。这种情况下,通常我们会采用一种称为“稀疏数组”或“标记”的技巧来实现。 数组的长度是其...

    MATLAB-求数组长度.docx

    在MATLAB中,可以使用length函数来求取数组的长度(或者称为数组的元素个数)。length函数返回数组的最大维度大小。下面是一些示例来说明如何使用length函数来求取数组的长度: 一维数组的长度: Matlab code arr ...

    matlab求数组长度 matlab怎么得到数组长度,MATLAB:使⽤字段作为结构数组 确定结构数组的总长度⼤⼩

    matlab怎么得到数组长度,MATLAB:使⽤字段作为结构数组 确定结构数组的总长度⼤⼩... 我有⼀个结构数组包含字段作为不同长度的结构数组.例如: ‘s’是⼀种结构 ‘data’是’s’中的⼀个字段,也是⼀个结构数组本⾝ ...

    结构体零长度数组的意义(入门)1

    在结构体中定义一个零长度数组,例如`char bytes[0]`,可以视为结构体的结束标志,但其真正的目的是为了后续的数据扩展。 结构体零长度数组的主要用途是作为可变长度的数据存储区。例如,在上述的`user_def_t`...

    遍历任意长度的数组

    本程序可以由用户确定数组的长度,再通过用户输入数组的值,遍历并打印出来

    结构体中最后一个数组长度为零

    在Linux系统里,/usr/include/linux/if_pppox.h里面有这样...使用起来非常方便,创建时,malloc一段结构体大小加上可变长数据长度的空间给它,可变长部分可按数组的方式访问,释放时,直接把整个结构体free掉就可以了。

    输入一个任意长度的数组,再对数组排序程序

    输入一个数组,数组的长度有用户输入,然后再一次输出数组的元素。

    所有奇数长度子数组的和(滑窗)1

    它首先初始化`sum`为0,然后使用一个循环从1开始,每次递增2(因为我们要找奇数长度的子数组),直到循环结束于数组长度`len`。在每次循环中,调用`windows`函数,传入当前的`i`(即窗口长度)和`arr`,并将返回的...

    数组中重复的数字_数组中重复的数字_

    找出数组中重复的数字。在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

    C++实现不定长数组

    传统的C++数组在声明时需要指定其长度,而不定长数组允许我们在运行时根据需要分配和调整大小。这种特性使得程序更加灵活,能更好地适应变化的数据需求。 在C++中,实现不定长数组的方式主要有两种:使用`std::...

    labview删除一维数组中的所有0元素

    For Loop通常用于已知数组长度的情况,而While Loop适用于未知长度或动态变化的数组。 4. **条件判断**:在循环内部,添加一个Condition Structure(条件结构),检查当前元素是否为0。可以使用Equal To?函数,将...

    matlab怎么求数组的长度和维数

    matlab怎么求数组的长度和维数matlab怎么求数组的长度和维数matlab怎么求数组的长度和维数matlab怎么求数组的长度和维数matlab怎么求数组的长度和维数matlab怎么求数组的长度和维数matlab怎么求数组的长度和维数...

    java数组优化实现修改数组长度.md

    此项实现了java数组不方便使用的优化,修护了数组不可更改长度的说话,面向对象的编程思想,小小提示可以当工具类使用

    易语言数组保存与恢复

    创建字节集 数组字节集, 长度 * 4 // 假设数组元素为整数,每个整数4字节 .循环 长度 .将 整数型 到 字节集 阵列元素[循环索引], 数组字节集, 4 // 将整数转换为字节集 .end循环 .写文件 “数组保存.txt”, 数组...

    C语言数组操作(长度、输出、拷贝、插入、删除、排序)

    有很详细的注释,可以作为一维数组操作函数进行参考。操作可供选择。 int length(int *array); 返回数组元素个数 int copyarray(int *src, int *dest); 成功返回0, 失败返回-1 int printarray(int *array); 打印 ...

    php按照定长把一纬数组拆分成二维数组.

    有时,我们可能需要将一个一维数组拆分为多个二维数组,每个子数组的长度是固定的。在这种情况下,PHP内建的函数可能无法直接满足需求,因此我们需要自定义函数来实现这一功能。下面我们将详细探讨如何实现“按定长...

    易语言数组中数值的查找

    如果 数组长度 <= 0 输出("数组为空!") .否则 左边界 := 0 右边界 := 数组长度 - 1 .循环 .如果 左边界 > 右边界 输出("未找到!") .跳出循环 .结束如果 .计算 (左边界 + 右边界) / 2, 查找位置 .如果 ...

    Linux shell数组循环的实例详解

    echo 数组的长度:${#arr[*]} for var in ${arr[@]} do echo 打印的内容:$var done 输出的内容如下: 以上就是Linux shell数组循环的实例详解,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助...

Global site tag (gtag.js) - Google Analytics