问题摘自《深度探究c++对象模型》:

struct mumble {
  /* stuff */
  char pc[ 1 ];
};【sizeof(mumble)是一个字节 。pc则代表的是指向这结构体中的这个字节的地址】

// grab a string from file or standard input【也就是下文的string,下文的string不是类型,是实际字符串】

// allocate memory both for struct & string
struct mumble *pmumb1 = ( struct mumble* ) malloc(sizeof(struct mumble)+strlen(string));  【这里不需要再加1了,尽管strlen是不包括\0的,因为pc中已经有一个字节了】              

strcpy( pmumb1->pc, string );【应该用变量名而不是结构体的名字,而且pc是指针了,不能再取地址了。】

下面答案摘自

把单一元素的数组放在一个struct的尾端  这个技巧可以用来在结构体中增加一个大小可以动态变化的字段,比如说一个buffer。pc其实就是一个指针,你可以申请一段内存,让pc指向它。

【那为什么一定要末尾呢,中间一个char pc[1]不行么?不行,如果是中间的话,就会把在他后面的数据给覆盖掉了。】

利用了下面的几个知识:
  1 c/c++当中指针的灵活性,指针相互之间是可以做转换的,没有类型条件限制内存地址可以按照不同类型的数据来解释
  2 struct 对象在内存当中的布局

malloc只负责分配一块指定大小的内存,并不做其他的事情,然后把内存的首地址返回
malloc关键词前面的(struct mumble *)强制类型转换,把这块内存转换为mumble类型数据了
实际上分配的内存要比一个mumble结构要大

memcpy这个函数是做内存当中数据的copy,它同样不检测数据的类型,即便是copy的数据超越了内存大小。
这个例子利用的也是这一点,把string当中的大量数据,copy到了mumble的pc变量所在的地址当中
因为malloc给这个地址分配了足够多的空间,copy超过1个char的数据到这里也不会产生实际的内存越界
后面对mumble.pc[n]  n>0 的访问,也是在malloc分配的空间当中,不会有异常

补充:

memcpy:内存复制  void *memcpy(void *dest, const void *src, size_t count);memcpy并不会遇到\0就结束,而是复制你在第三个参数中指定的字节数。
strcpy: 字符串复制    char * strcpy ( char * destination, const char * source );其复制遇到\0后就结束了

为什么 把单一元素的数组放在一个struct的尾端问题的更多相关文章

  1. 关于理解《C++ 对象模型》中:把单一元素的数组放在末尾,struct可以拥有可变大小的数组

    这一章在第19页,写的好深奥,我竟然没看明白在说什么--之后再看了几遍,终于明白了. 原文: C程序员的巧计有时候却成为c++程序员的陷阱.例如把单一元素的数组放在一个struct的末尾,于是每个st ...

  2. Leetcode 540.有序数组中的单一元素

    有序数组中的单一元素 给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数. 示例 1: 输入: [1,1,2,3,3,4,4,8,8] 输出: 2 示例 2: 输入 ...

  3. Java实现 LeetCode 540 有序数组中的单一元素(位运算入门)

    540. 有序数组中的单一元素 给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数. 示例 1: 输入: [1,1,2,3,3,4,4,8,8] 输出: 2 示例 ...

  4. 每天php函数 - 数组最后一个元素取出

    复制代码代码如下: $array=array(1,2,3,4,5);    echo $array[count($array)-1];//计算数组长度,然后获取数组最后一个元素,如果数组中最后一个元素 ...

  5. php删除数组中相同的元素,只保留一个相同元素

    <?php// 删除数组中相同元素,只保留一个相同元素function formatArray($array){sort($array);$tem = ”;$temarray = array() ...

  6. JavaScript利用数组原型,添加方法实现遍历多维数组每一个元素

    原型就是提供给我们为了让我们扩展更多功能的. 今天学习了用js模拟底层代码,实现数组多维的遍历.思想是在数组原型上添加一个方法. // js中的数组forEach方法,传入回掉函数 能够帮助我们遍历数 ...

  7. jQuery根据元素值或元素下标来删除一个数组元素及数组对象方法列表

    在前提不知道b在这个数组的下标,删除b这个元素  var arrList = ['a','b','c','d'];         arrList.splice(jQuery.inArray('b', ...

  8. js 获取数组最后一个元素

    当然有很多中做法 我这边就随便写几个最常用 最简单的方法把 # shift 删除数组第一个元素,并返回该元素,跟pop差不多 var a = ["aa","bb" ...

  9. 【C语言】求旋转数组的最小数字,输入一个递增排序的数组的一个旋转,输出其最小元素

    //求旋转数组的最小数字,输入一个递增排序的数组的一个旋转,输出其最小元素 #include <stdio.h> #include <string.h> int find_mi ...

随机推荐

  1. 数据库(MySQL)表基本操作

                                    数据库表基本操作 思前想后,最终还是把博客的名字改成了数据库表基本操作,以前叫SQL语句大全,感觉用"大全"这个名词 ...

  2. Myeclipse 2016 CI 6 破解

    Myeclipse 2016 CI 6 破解 2016-10-11 分类:Javaweb后台 / JSP / 首页 阅读(1633) 评论(16)  之前写了myeclipse 2015 stable ...

  3. JMeter处理Cookie与Session

    1.Cookie 添加方式:线程组-配置元件-HTTP Cookie 管理器,如下图: 2.Session 添加方式:线程组-前置处理器 -HTTP URL 重写修饰符,如下图: 有些tomcat的s ...

  4. 【NOIP2014】DAY2题解+代码

    T1 傻逼题……不想写贴昨年代码了. 总之随便怎么搞都能过. 15年的DAY2T1怎么那么毒瘤真是越活越倒退] #include <iostream> #include <fstre ...

  5. 开源的许可证GPL、LGPL、BSD、Apache 2.0的通俗解释

    软件开发者要开源软件,不单单是开放源代码就可以了,选择一种许可证很重要,一个许可证之于软件就相当于价值观之于普通人,代表了这个软件的基本品性.一个错误的许可证选择可能会直接导致整个项目的失败. 各种开 ...

  6. windows 上搭建 sftp 服务器 --freesshd

    Linux 下 sftp 默认都会安装的, Windows 就没有了.网上搜的资料发现比较好用的是 freesshd,免费版中最好用的. 1,下载:http://www.freesshd.com/?c ...

  7. C# IIS7.0+ Web.Config 配置Session过期时间

    1. 2. 3. <sessionState mode="InProc" timeout="120"></sessionState>

  8. idea新建项目文件名为红色的解决办法

    Perference->version Control ->Directory添加项目路径,vcs选<none> 即可.

  9. webp图片详解

    WebP(发音 weppy),是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8.根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使 ...

  10. Zeppelin使用报错

    报错信息: INFO [2016-11-03 17:05:08,481] ({pool-2-thread-2} SchedulerFactory.java[jobFinished]:137) - Jo ...