使用struct完成一个可变长数组

《c++深度探索对象模型》 P20:

c++中凡是处于同一个access section(访问区段,也就是private,public这些)中的数据,必定保证以声明顺序出现在内存布局当中。但是多个access section中的各笔数据,排列顺序就不一定了。

对于从c发展来的结构体,除了与类在默认访问权限上不同,内存布局上也存在区别。对于struct,是按照声明顺序来存放数据的。

可以利用这点,完成一个可变长数组,方法如下:

将单一元素的数组放到struct末尾。示例:

// 深度探索c++对象模型_chapter_1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <string>

using namespace std;

namespace StructClassCompare {
    //struct 数据成员内存按照声明顺序排列,将单一元素的数组放到struct末尾,即可完成一个可变长数组.
    //这样完成一个可变长数组的好处: 内存连续,减少内存碎片
    struct mumble{
        int  a = 0;
        char pc[1];//这里如果直接使用指针,那么需要先分配结构体一次,然后再为结构体内指针分配一次内存,
        //这样结构体内部的内存就不是连续的了
    };

    void test( ) {
        const char* pstr = "123";
        struct mumble* pmumb1 = (struct mumble*) malloc( sizeof(struct mumble) + strlen(pstr) + 1);//+1是因为char* 末尾的结束符
        cout << sizeof(struct mumble) << "  : " <<strlen(pstr)<< endl;// 8  3

        cout << sizeof(pmumb1->a) << "  : " << sizeof(pmumb1->pc) << endl;// 4  1
        cout << &pmumb1->a << "  :   " << &pmumb1->pc << endl;//00CAFBB0  :   00CAFBB4内存连续的

        strcpy_s(pmumb1->pc, strlen(pstr)+1, pstr);//在拷贝时,pstr大小是超出pmumb1->pc大小的,
        //但是并没有超出pmumb1大小,并且由于结构体内存连续,且pc数组位于结构体末尾,因此可以完成拷贝并读取

        cout << pmumb1->pc << endl;//输出123      
        cout << &pmumb1->a << "  :   " << &pmumb1->pc << endl;//00CAFBB0  :   00CAFBB4
        cout << sizeof(pmumb1->a) << "  : " << sizeof(pmumb1->pc) << endl;//4  : 1
    }
}

int main()
{
    StructClassCompare::test();    
}

从上面的输出可以看到  拷贝前(strcpy_s(pmumb1->pc, strlen(pstr)+1, pstr);语句前) 输出pumub1->pc大小是1

拷贝后(strcpy_s(pmumb1->pc, strlen(pstr)+1, pstr);语句后) 输出pumub1->pc大小也是1

但是pumub1->pc一样输出了 pstr指向的“123”。

这是因为

1.数组是连续存储的空间,因此读取字符数组只要有首地址即可。因此,这里要做的只是将字符串存储在以pc[0]开头的首地址后续的那片存储空间

2.虽然pmumb1->pc的大小只有1,但是给pmumb1 多分配了strlen(pstr) + 1大小的空间,足够存放pstr指向的“123”,所以空间是足够的。

 

参考:https://blog.csdn.net/xiongping_/article/details/53579953
https://blog.csdn.net/damotiansheng/article/details/40958299?utm_source=blogxgwz1
https://www.cnblogs.com/cy568searchx/p/3655193.html

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值