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> # ...
随机推荐
- Spring MVC过滤器-登录过滤
以下代码是继承OncePerRequestFilter实现登录过滤的代码: package com.test.spring.filter; import java.io.IOException; im ...
- tcp 代理的作用
http://www.h3c.com.cn/Service/Document_Center/IP_Security/FW_VPN/F1000-E/Configure/Operation_Manual/ ...
- ubuntu修改默认系统启动项
sudo gedit /etc/default/grub 文件中有一段: GRUB_DEFAULT= 0代表默认从第一项启动 1代表从第二项启动 依次类推 将数字改成你想要启动的 修改完保存关闭,然后 ...
- session 防止表单重复提交
防止表单重复提交应该现在前台做一遍,再在后台做一遍.这样双重安全而且减轻服务器负担. 代码: package flying.form; import java.io.IOException; impo ...
- Cookie技术
u 常用的API 创建Cookie对象 Cookie(String name, String value) ->以指定数据创建Cookie对象 设置Cookie对象 void setMa ...
- JSON对象和JSON字符串以及JSON.parse 函数的使用
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- s:if 标签用法总结和举例
http://www.360doc.com/content/11/1108/18/6161903_162838014.shtml
- Django URL中r的意思
例如: urlpatterns = patterns('', # ... (r'^time/plus/\d+/$', hours_ahead), # ... ) 正则表达式字符串的开头字母“r”. 它 ...
- unity, StartCoroutine and StopCoroutine
startCoroutine("func",1.0f)可以用stopCoroutine("func")来停. startCoroutine(func(1.0f) ...
- linux学习规划