C语言技巧:把单一元素的数组放在末尾,struct可以拥有可变大小的数组

《C++ 对象模型》第19页有这样一句话
C程序员的巧计有时候却成为c++程序员的陷阱。例如把单一元素的数组放在一个struct的末尾,于是每个struct objects可以拥有可变数组的数组:

struct mumble
{/* stuff */char pc[1];  
};//从文件或标准输入装置中取得一个字符串
//然后为struct 本身和该字符配置足够的内存struct mumble * pmumbl = (struct mumble*)malloc(sizeof(struct mumble) + strlen(string) +1);
strcpy(&mumble.pc,string);

正好之前看MCP++的cache acess组件的时候也发现THashMap等结构体在结构体末尾使用了单一元素的数组,说明这一技巧确实用的广泛,现在看看其原理:
结构体的末尾定义了一个char数组,只分配了1个字符。那怎么能说是可变大小数组。
malloc函数分配了一堆的内存。大小为结构体+字符串+1(字符串结束符)
指针pmumbl指向的是malloc所分配的整个内存,而pmumbl->pc指向的是这块内存的第一个字节,因为malloc操作为整个string分配了足够的内存,所以在strcpy的时候,虽然溢出了pc的内存范围,但没有溢出struct的内存范围,使得strcpy的结果就是合理的且可控的。相当于struct拥有了可变大小的数组
在这里插入图片描述
C++中 public、protected、private内的声明顺序可以被保证,但是这三个关键字的布局是不同的。因此总的排列顺序并不能被保证。因此,不一定能实现struct的可变大小的数组,建议是不要那么做。
下面看一下代码验证:

#include <iostream>
#include <string.h>
using namespace std;typedef struct mumble
{/* stuff */char pc[1];
} mumble;
int main(int argc, char **argv){mumble raw;raw.pc[0] = 'a';cout << "raw " << sizeof(raw) << endl;char str[10] = "abcdefgxa";mumble* mumptr = (mumble*)malloc(sizeof(mumble) + strlen(str));strcpy_s(mumptr->pc,strlen(str) + 1, str);cout << "mumptr " << sizeof(*mumptr) << endl;cout << mumptr->pc << endl;free(mumptr);
}

打印结果:sizeof并不能获取mumptr的真实大小,但是通过下标访问确实能够访问到pc

raw 1
mumptr 1
abcdefgxa

内存分布图:
在这里插入图片描述
会发现内存中确实有值:
在这里插入图片描述
所以以后定义可变包结构时候,结构中没有可变包的大小,而是只要在结构里最后加一个元素的字节数组就可以。

参考:
https://blog.csdn.net/qq_35749455/article/details/116356006

https://blog.csdn.net/weixin_30855761/article/details/99864866?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3.pc_relevant_default&utm_relevant_index=5

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探讨C++ 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别(二)...

看此文&#xff0c;务必需要先了解本文讨论的背景&#xff0c;不多说&#xff0c;给出链接&#xff1a; 探讨C 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别&#xff08;一&#xff09; 本文会以此问题作为讨论的实例&#xff0c;来具体讨论以下四个问题&a…

后台系统可扩展性学习笔记(一)概要

文章目录系统大致架构可扩展性负载均衡器与会话保持引入冗余增强系统可用性缓存减轻数据库压力异步处理参考系统大致架构 当一个用户请求从客户端出发&#xff0c;经过网络传输&#xff0c;达到 Web 服务层&#xff0c;接着进入应用层&#xff0c;最后抵达数据层&#xff0c;它…

poj 3728(LCA + dp)

题目链接&#xff1a;http://poj.org/problem?id3728 思路&#xff1a;题目的意思是求树上a -> b的路径上的最大收益&#xff08;在最小值买入&#xff0c;在最大值卖出&#xff09;。 我们假设路径a - > b 之间的LCA(a, b) f, 并且另up[a]表示a - > f之间的最大收益…

成功之路

1、每天都要有进步&#xff0c;都要有新知识的收获。 2、工作认真负责&#xff0c;高效的完成&#xff0c;多总结。 3、自己多练习一些感兴趣的东西&#xff0c;实践&#xff01;&#xff01;&#xff01; 4、写博客。 5、百度、腾讯、阿里是目标&#xff0c;差距还很大&#x…

后台系统可扩展性学习笔记(二)权衡取舍

文章目录性能与可扩展性延迟与吞吐量可用性与一致性一致性模式可用性模式可用性衡量参考系统设计中也面临许多权衡取舍&#xff1a;性能与可扩展性延迟与吞吐量可用性与一致性 性能与可扩展性 可扩展&#xff0c;意味着服务能以加资源的方式成比例地提升性能&#xff0c;性能…

iOS中使用子线程的完整方法

第一步&#xff1a;开启子线程 //开启子线程到网络上获取数据myFirstThread [[NSThread alloc]initWithTarget:self selector:selector(thread1GetData) object:nil];[myFirstThread setName:"第一个子线程,用于获取网络数据"];[myFirstThread start]; 第二步&…

DIV的表单布局

表单布局其实用表格最好了&#xff0c;可是表格的话&#xff0c;无法定位&#xff0c;这个是一个硬伤。 <!DOCTYPE html> <html> <head> <meta charset"utf-8" /> <title>表单布局</title> <link rel"stylesheet" …

后台系统可扩展性学习笔记(三)DNS机制原理

文章目录DNS概念梳理域名基本概念资源记录基本概念路由策略DNS 域空间结构实现原理复制机制查询机制缓存机制参考DNS概念梳理 DNS&#xff08;Domain Name System&#xff09;相当于互联网的通讯录&#xff0c;能够把域名翻译成 IP 地址。 从技术角度来讲&#xff0c;DNS 是个…

后台系统可扩展性学习笔记(四)CDN机制原理

文章目录概念梳理CDN拓扑结构CDN内容分发方式架构原理工作原理实现原理概念梳理 CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;是由分布在不同地理位置的代理服务器及其数据中心组成的网络&#xff0c;希望在空间距离上为用户就近提供服务&am…

Javascript 基础—变量 运算符

经过找工作笔试的洗礼&#xff0c;感觉自己js语法方面掌握的不是很系统&#xff0c;今天来梳理下——变量以及运算符。 基础篇 和C语言的不同点&#xff1a;是一种弱类型语言&#xff0c;申明变量时不需要指定类型&#xff1b;变量名的命名方法也有不同&#xff1b;简单类型种类…

后台系统可扩展性学习笔记(五)负载均衡

文章目录Load balancer(负载均衡器)请求传输拆解DNS 负载均衡客户端负载均衡OSI 七层模型回顾2 层、3 层负载均衡3/4 层负载均衡7 层负载均衡在 第一节谈到了系统的横向扩展在于从单机扩展到多机&#xff0c;那么面临的第一个问题就是这些机器如何协同工作&#xff0c;即如何调…

Struts2第一个工程helloStruts极其基本配置

前面已经准备好了Struts-2.3.15&#xff0c;现在就可以直接搭建Struts2的工程了。前面http://blog.csdn.net/huangchnegdada/article/details/9179041有对Struts-2.3.15的准备工作的详述。 首先打开MyEclispe新建一个Web Project&#xff0c;名字就叫Struts2_0100_Introduction…

[LeetCode]Find Minimum in Rotated Sorted Array

题目描述&#xff1a; Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). Find the minimum element. You may assume no duplicate exists in the array. 解题方案&#xff1a; 直接贴代码&…

后台系统可扩展性学习笔记(六)反向代理

文章目录Web代理服务反向代理反向代理作用Web代理服务 Web 代理服务指的是在客户端资源请求和提供这些资源的 Web 服务之间充当中介的角色&#xff0c;代理服务可以实现在客户端&#xff0c;或者从客户端到目标服务器中间的任意环节。 例如&#xff0c;客户端不直接向提供目标…

(C)单链表

老师版 1 #include <stdio.h>2 #include <stdlib.h>3 4 // 定于Node数据类型5 struct Node6 {7 int data; // 数据域8 struct Node *next; // 指针域9 };10 11 // 创建一个单链表&#xff0c;并把head节点返回&#xff1b;…

实验:sigsuspend(),sigprocmask()

实验&#xff1a;sigsuspend(),sigprocmask()源代码&#xff1a;/* * Program: pause_suspend.c * To test the difference between sigsuspend() and paus(). * Author: zsl * Date: 2014-10-17 * First release. * 参见网页&#xff1a;http://blog.csdn.net/liwentao1091/ar…

后台系统可扩展性学习笔记(七)Service Discovery与微服务

文章目录应用层微服务架构服务注册查询 Service Discovery客户端 Service DiscoveryDNS-SD DNS-based Service Discovery服务端 Service Discovery服务注册与注销自注册模式第三方注册模式总结参考应用层 在简单的 3 层结构中&#xff0c;Web 服务层既要处理请求&#xff0c;又…

很久没写代码了,这(那)几天真是累死了。。。先写一个幻方的程序吧

1 #include <stdio.h>2 #include <stdlib.h>3 #include <windows.h>4 5 #define EVEN_DOUBLE_4 4 //双偶的最基本类型&#xff0c;4阶双偶6 #define SCREEN_SIZE 19 //屏幕显示不变形的最大尺寸&#xff08;主要是因为窗口大小限制&#xff09;7 #defi…

#pragma once

http://baike.baidu.com/view/1276747.htm?fraladdin 转载于:https://www.cnblogs.com/prayer521/p/4069040.html