C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++变长数组

C++结构体中变长数组的使用问题分解刨析

作者:柒号华仔

变长数组在C++中指的是集合(也叫容器)如vector就是C语言中,所有的数组都不定长,没有下标越界的概念,数组实质就是一个指针(由数组名充当)因此C语言中数组的长度没有任何意义平常在C语言中讲的不定长数组,其实就是指针

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. 结构体变长数组使用要点

到此这篇关于C++结构体中变长数组的使用问题分解刨析的文章就介绍到这了,更多相关C++变长数组内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文