C语言0长度数组(柔性数组)
在标准 C 和 C++ 中,不同意用 0 长度数组,但在
GNU C 中,却能够定义 0 长度数组(在C99之前写成长度为0,C99中能够直接不写索引)。一般会拿手冊中给的样例来说明
struct line {
int length;
char contents[0]; // char contents[]; //C99
}
从打印出来的结构体尺寸 sizeof (struct line) = 4 (和编译器有关,看内存对齐规则),能够看到contents[0]不占有空间(不同于字符指针类型),它存在的优点是在结构体的后面同意我们自己申请一定大小的存储空间,而不是每次都使用 MAX_SIZE 大小的结构体。通常的用法例如以下:
int this_length = 60;struct line *thisline = (struct line *)malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
通过測试代码能够发现:为0长度数组分配的空间紧跟着该该结构体最后一个字段之后,并且释放结构体指针后。我们自己分配的空间也会释放(不同于有些网上的说法)。所以须要注意的是我们释放的是由某个指针指向的内存空间,而非指针,指针变量是在程序结束后回收的,所以在我们释放一段内存之后要将其置为NULL,否则还是能够訪问的,只是訪问到的都是垃圾数据。
#include <stdio.h>
#include <stdlib.h> struct line {
int length;
char test;
char contents[0];//or <span style="font-family: Arial, Helvetica, sans-serif;">char contents[];</span>
}; int main(){
int i; int this_length = 60;
struct line *thisline = (struct line *)malloc (sizeof (struct line) + this_length);
thisline->length = this_length; printf ("thisline addr is %p\n", thisline);
printf ("thisline->length field value is %d\n",thisline->length);
printf ("thisline->length field addr is %p\n", &thisline->length);
printf ("thisline->test field addr is %p\n", &thisline->test);
printf ("thisline->contents field addr is %p\n", &thisline->contents);
printf ("thisline->contents[0] addr is %p\n", &thisline->contents[0]);
printf ("thisline->contents[0] addr is %p\n", &thisline->contents[1]); for(i=0; i<3; i++){
thisline->contents[i] = 'a' + i;
} char *p = thisline->contents;
printf("%c\n", p[2]); free(thisline);
//After free , when we access the space ,we got garbage data;
printf("%d\n", thisline->length);
printf("%c\n", p[2]); return 0;
}
执行效果:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> struct line {
int length;
char test;
char contents[0];
}; int main(){
int i;
char s[20] = "Hello World.";
int that_length = 60;
struct line thisline = {5, 'A', {'a', 'b', 'c'}}; struct line *thatline = malloc(sizeof(struct line) + that_length);
thatline->length = that_length;
for(i=0; i<3; i++){
thatline->contents[i] = 'A' + i;
} char *p = thatline->contents;
printf("%c\n", p[2]); free(thatline->contents);
thatline->contents = thisline.contents;
// error: incompatible types when assigning to type ‘char[]’ from type ‘char *’
p = thatline->contents;
printf("%c\n", p[2]); return 0;
}
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdm9uemhvdWZ6/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
#include <stdio.h>
#include <stdlib.h>
#include <string.h> struct line {
int length;
char test;
char contents[];
}; int main(){
struct line thisline = {5, 'A', {'a', 'b', 'c'}}; return 0;
}
能够看到严格的弹性数组和长度0的数组还是有差别的,这里就不能使用静态初始化。仅仅能像FlexibleArray1.c中那样操作。
C语言0长度数组(柔性数组)的更多相关文章
- 柔性数组(Redis源码学习)
柔性数组(Redis源码学习) 1. 问题背景 在阅读Redis源码中的字符串有如下结构,在sizeof(struct sdshdr)得到结果为8,在后续内存申请和计算中也用到.其实在工作中有遇到过这 ...
- (转)C语言中长度为0的数组
前面在看Xen的源码时,遇到了一段代码,如下所示: 注意上面最后一行的代码,这里定义了一个长度为的数组,这种用法可以吗?为什么可以使用长度为0 的数组?长度为的数组到底怎么使用?……这篇文章主要针对该 ...
- C语言柔性数组
结构中最后一个元素允许是未知大小的数组,这个数组就是柔性数组.但结构中的柔性数组前面必须至少一个其他成员,柔性数组成员允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内 ...
- C语言柔性数组讲解
#include<stdio.h> typedef struct _SoftArray{ int len; int array[]; }SoftArray; int main() { ; ...
- C语言的柔性数组的实现及应用
c编程的时候数组长度一般都是固定好的,实际上c还能实现变长数组.其实c99中确实是有变长数组的说法,C99中通过允许结构体中的最后一个成员是长度未知的数组实现变长数组,其定义格式如下: typedef ...
- C语言柔性数组和动态数组
[前言]经常看到C语言里的两个数组,总结一下. 一.柔性数组 参考:https://www.cnblogs.com/veis/p/7073076.html #include<stdio.h> ...
- C/C++ 中的0长数组(柔性数组)
转自C/C++ 中的0长数组(柔性数组) 在标准C和C++中0长数组如charArray[0]是不允许使用的,因为这从语义逻辑上看,是完全没有意义的.但是,GUN中却允许使用,而且,很多时候,应用在了 ...
- 深入浅出C语言中的柔性数组
在日常的编程中,有时候需要在结构体中存放一个长度动态的字符串,一般的做法,是在结构体中定义一个指针成员,这个指针成员指向该字符串所在的动态内存空间,例如: typedef struct test { ...
- (四)C语言柔性数组、指针赋值
一.柔性数组 今天看了公司的代码,发现一个很奇怪的问题,后来自己写了类似代码,我先把代码贴出来吧. #include<stdio.h> #include<string.h> # ...
随机推荐
- QtGui.QSplitter
A QtGui.QSplitter lets the user control the size of child widgets by dragging the boundary between t ...
- CLR_Via_C#学习笔记之CLR的执行模型
1:公共语言运行时(Common Language Runtime,CLR)是一个可由多种编程语言使用的“运行时”.CLR的核心功能(比如内存管理.程序集加载.安全性.异常处理和线程同步)可由面向CL ...
- 完整的JavaScript版的信用卡校验代码
function isValidCreditCard(type, ccnum) { if (type == "Visa") { // Visa: length 16, prefix ...
- 解决 android sdk 下载慢
1. 配置host: 74.125.237.1 dl-ssl.google.com 2.设置强制使用http连接
- <a>标签实现锚点跳跃,<a>标签实现href不跳跃另外加事件(ref传参)
1.锚点跳跃 HTML: <div class="page_title" id="maodian"> <h1>客房节日价格管理</ ...
- 如何在 Android 手机上安装 Ubuntu 13.04
在农村,一切都是相对的. 长话短说,我已经厌倦了我们在农村做的一个小小的突破. 我本该去放松,读了一大堆东西涉及到自然语言的处理.但是因为我这些天一直在修改LXC和chroot的时候,我决定将我的An ...
- FFmpeg音视频同步示例
原文地址:https://my.oschina.net/u/555002/blog/79324 前面整个的一段时间,我们有了一个几乎无用的电影播放器.当然,它能播放视频,也能播放音频,但是它还不能被称 ...
- 完善String类([]、 +、 += 运算符重载)、>>和<<运算符重载
在前面文章中使用过几次String类的例子,现在多重载几个运算符,更加完善一下,并且重载流类运算符. []运算符重载 +运算符重载 +=运算符重载 <<运算符重载 >>运算符重 ...
- HDU 4280Island Transport(网络流之最大流)
题目地址:pid=4280">http://acm.hdu.edu.cn/showproblem.php? pid=4280 这个题是一个纯最大流模板题..就是用来卡时间的.. 还好我 ...
- 简单认识DataSet与DataTable
DataSet 是放在内存中的,对DataSet中数据的修改并不直接反应到数据库,要通过 DataAdapter 的 Update 方法更新回数据库; DataSet相当你用的数据库: DataTab ...