c语言结构体中动态数组的使用

【背景】

c语言结构体中动态数组使得用户能够根据需要来申请空间,相比静态数组,更能有效利用存储空间。

【正文】

1. 动态数组在结构体中间

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
        int a;
        char buf[0];    // 或者char buf[];
        int b;
}Node;

int main()
{
        printf("%d\n", sizeof(Node));

        Node *p = (Node *)malloc(sizeof(Node) + 16);
        p->a = 1;
        p->b = 2;
        strcpy(p->buf, "hello");

        printf("node : %p\n", p);
        printf("node::a : %p, %d\n", &p->a, p->a);
        printf("node::b : %p, %d\n", &p->b, p->b);
        printf("node::buf : %p, %s\n", p->buf, p->buf);

        free(p);

        return 0;
}

运行结果:

8
node : 0x1d1f010
node::a : 0x1d1f010, 1
node::b : 0x1d1f014, 1819043176
node::buf : 0x1d1f014, hello

结构体中b与buf的内存地址一样,造成内存区域覆盖。

2. 动态数组在结构体末尾

typedef struct
{
        int a;
        int b;
        char buf[0];    // 或者char buf[];
}Node;

int main()
{
        printf("%d\n", sizeof(Node));

        Node *p = (Node *)malloc(sizeof(Node) + 16);
        p->a = 1;
        p->b = 2;
        strcpy(p->buf, "hello");

        printf("node : %p\n", p);
        printf("node::a : %p, %d\n", &p->a, p->a);
        printf("node::b : %p, %d\n", &p->b, p->b);
        printf("node::buf : %p, %s\n", p->buf, p->buf);

        free(p);

        return 0;
}

运行结果:

8
node : 0xfbb010
node::a : 0xfbb010, 1
node::b : 0xfbb014, 2
node::buf : 0xfbb018, hello

【结论】

1. 结构体中动态数组对sizeof无贡献

2. 动态数组使用时放在结构体末尾。

【实际使用】

redis中sds.h使用的就是动态数组:

struct sdshdr {
    unsigned int len;
    unsigned int free;
    char buf[];
};

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 18:48:23

c语言结构体中动态数组的使用的相关文章

在C语言结构体中添加成员函数

我们在使用C语言的结构体时,经常都是只定义几个成员变量,而学过面向对象的人应该知道,我们定义类时,不只是定义了成员变量,还定义了成员方法,而类的结构和结构体非常的相似,所以,为什么不想想如何在C语言结构体中添加成员变量呢 在C语言的结构体中是不能直接定义成员函数的,这点和C++不同,但是我们可以通过定义一个函数指针的方式来指向一个方法. 示例代码如下: 1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef struct node 4

C语言 结构体中的成员域偏移量

//C语言中结构体中的成员域偏移量 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct _student{ char name[30];//32 int num; }Student; void main(){ Student *p = NULL; printf("%x\n", p);//打印 0 p

C语言结构体中的函数指针

这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址:http://www.cnblogs.com/archimedes/p/function-pointer-in-c-struct.html,转载请注明源地址. 引言 指针是C语言的重要组成部分, 于是深入理解指针并且高效地使用指针可以使程序员写出更加老练的程序.我们要记住指针是一个指向内存地址的变量.指针可以引用如int.char……常见的数据类型,例如: int * intptr; // 声明一个指向整型值的

为什么结构体中的数组不能用const int变量指定大小?

typedef struct {                int semId;                 int counter;     char str[MAX_STRING];  }MY_BLOCK_T; int main() {       MY_BLOCK_T mybt;    //编译时这里报错 ??     char str2[MAX_STRING];  //这里没有错 !!       return 0; } 编译器不同,编译的结果也是不同的,标准C不支持变量声明声明

C语言结构体赋初值

C语言结构体赋初值,特别是结构体中含有数组成员是,最后一个逗号最好是不要多写.因为有些时候可能会出错.图中,红色的框框处.

结构体中指针赋值问题的分析及C代码示例

问题描述 某结构体的定义如下: typedef struct { int iAge; // 年龄 char szAddr1[100]; // 地址1 char *pszAddr2; // 地址2 char **pszAddr3; // 地址3 } T_PeopleInfo; 请问如何对结构体中的各个成员变量(尤其是指针变量)进行赋值? 问题分析及C代码示例 我们可以看到,在结构体T_PeopleInfo中,pszAddr2和pszAddr3均为指针,其中pszAddr2为一级指针,pszAddr

对于结构体中内存对齐的简单说明

结构体内存对齐的原因: 在运行一个结构体时,编译器需要给结构体中的每个变量成员分配内存空间,如这样一个结构体中 typedef struct A { char c1; int i; int j; }A; 对其内存空间分配问题进行分析,如若不进行内存对齐,它的内存空间是: char类型变量c1占1个字节,紧接着int类型变量i与j分别占4个字节,总有9个字节,在访问时,如图1,访问次数较多:在图2中,总有12个字节空间,虽然浪费了c1后的三个字节空间,访问次数却变少,会很大程度上节省了时间,提高了

C语言——结构体数组的使用案例(如何判断两个矩形是否相交,其中一个是否包含在另外一个里面,点是否在矩形中)

Rect.h struct CPoint { float x; float y; }; typedef struct CPoint CPoint; struct CSize { float width; float height; }; typedef struct CSize CSize; struct CRect { CPoint origin; CSize size; }; typedef struct CRect CRect; //判断两个矩形是否相交 BOOL isIntersecti

结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:(1).不需要初始化,数组名直接就是所在的偏移:(2).不占任何空间,指针需要占用int长度空间,空数组不占任何空间.“这个数组不占用任何内存”,意味着这样的结构节省空间:“该数组的内存地址就和它后面的元素地址相同”,意味着无需初始化,数组名就是后面元素的地址,直接就能当指针使用. 这样的写法最适合制作动态buffer,因为可以这样分配空间malloc(sizeof(struc