【C/C++】结构体中使用变长数组问题分析

简介: 在结构体里面使用变长数组来封装消息体,运行程序时弹出一些错误,问题已经解决,由于源程序不方便截取,现在通过一个实例来复现问题。
作者: 柒号华仔
个人主页: 欢迎访问我的主页
个人信条:星光不问赶路人,岁月不负有心人。
个人方向:专注于4G/5G领域,同时兼顾其他网络协议,编解码协议,C/C++,linux等,感兴趣的小伙伴可以关注我,一起交流。


@TOC

1. 问题来源

今天在结构体里面使用变长数组来封装消息体,运行程序时弹出如下错误:

*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)

问题已经解决,由于源程序不方便截取,现在通过一个实例来复现问题。


2. 问题复现

2.1 初始程序

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

typedef struct {
    int a;
    char body[];
} msg_t;

int main(void)
{
    msg_t msg;
    char *pdu = "abcdefg";
    strcpy(msg.body,pdu);
    printf("msg body:%s\n",msg.body);

    return 0;
}

上述程序编译是没有问题的,但如果带变长数组的结构体换两种写法,会复现两种错误。


2.2 独立变长数组复现

typedef struct {
    char body[];
} msg_t;

结构体中只有变长数组body[],无其他成员。编译错误如下:

test.c:7:10: error: flexible array member in a struct with no named members
     char body[];

这种情况在实际中并不会出现,如果只有一个成员,就没必要多一层结构体。


2.3 变长数组置前复现

typedef struct {
    char body[];
    int a;
} msg_t;

变长数组body[]不为结构最后一个成员。编译错误如下:

test.c:7:10: error: flexible array member not at end of struct
     char body[];

这种情况就是按照C99标准变长数组必须是结构体的最后一个成员。


2.4 缓冲区溢出复现

运行编译出的可执行程序,打印错误如下:

msg body:abcdefg
*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)

这里是因为没有为变长数组body分配内存,检测到了缓冲区溢出,通过如下表达式分配内存:

msg_t *msg= (msg_t*)malloc(sizeof(msg_t)+16*sizeof(char));

这样就为结构体指针msg分配了一块内存空间,程序变为:

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

typedef struct {
    int a;
    char body[];
} msg_t;

int main(void)
{
    msg_t *msg = (msg_t*)malloc(sizeof(msg_t)+16*sizeof(char));
    char *pdu = "abcdefg";

    strcpy(msg->body,pdu);
    printf("msg body:%s\n",msg->body);
    free(msg);

    return 0;
}

编译成功,运行结果正常:

msg body:abcdefg


3. 结构体变长数组使用要点

  • 结构体中不能只有变长数组一个成员,同时变长数组必须为结构体最后一个成员。
  • 变长数组不占用结构体的存储空间,长度为0,数组名只是一个占位符。sizeof()计算结构体大小时,变长数组在其中长度为0。
  • 使用变长数组结构体时,用malloc()分配内存空间。使用完毕用free()可以直接释放整个结构体的空间。
相关文章
|
2月前
|
存储 算法 编译器
【C++ 字符数组的模板特化】面向字符串的C++模板特化:理解与实践
【C++ 字符数组的模板特化】面向字符串的C++模板特化:理解与实践
54 1
|
2月前
|
存储 缓存 安全
C++数组全解析:从基础知识到高级应用,领略数组的魅力与技巧
C++数组全解析:从基础知识到高级应用,领略数组的魅力与技巧
54 1
|
15天前
|
存储 C++
【C++模板】模板实现通用的数组
【C++模板】模板实现通用的数组
|
20天前
|
存储 人工智能 C++
【重学C++】【指针】详解让人迷茫的指针数组和数组指针
【重学C++】【指针】详解让人迷茫的指针数组和数组指针
34 1
|
1月前
|
C++ 索引
C++ 获取数组大小、多维数组操作详解
本文介绍了如何获取数组的大小和使用`sizeof()`运算符。`sizeof()`返回数组所占字节数,而非元素个数。要获取元素个数,需除以单个元素的大小。此外,文章展示了如何使用`sizeof()`遍历数组,包括多维数组。多维数组是数组的数组,可用来表示网格。文中以战舰游戏为例说明了多维数组的应用。最后提到了微信公众号`Let us Coding`以获取更多内容。
22 0
|
1月前
|
C++
C++结构体
C++结构体
|
1月前
|
存储 C++ 索引
C++数组
C++数组
|
1月前
|
C++
C++语言学习数组和字符串应用案例
【4月更文挑战第8天】该文展示了C++中数组和字符串的应用案例。数组示例定义了一个整数数组并访问、修改其元素,计算了元素之和。字符串示例中,定义了一个字符串并遍历、修改字符,进行了字符串拼接、查找子字符串及替换操作。
12 3
|
1月前
|
NoSQL C++
c++中包含string成员的结构体拷贝导致的double free问题
c++中包含string成员的结构体拷贝导致的double free问题
12 0
|
2月前
|
设计模式 算法 编译器
【C++ 泛型编程 入门篇】C++ 元编程 :模板结构体的的使用教程
【C++ 泛型编程 入门篇】C++ 元编程 :模板结构体的的使用教程
68 1