问题摘自《深度探究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. [DL学习笔记]从人工神经网络到卷积神经网络_3_使用tensorflow搭建CNN来分类not_MNIST数据(有一些问题)

    3:用tensorflow搭个神经网络出来 为什么用tensorflow呢,应为谷歌是亲爹啊,虽然有些人说caffe更适合图像啊mxnet效率更高等等,但爸爸就是爸爸,Android都能那么火,一个道 ...

  2. asp.net core + mysql + ef core + linux

    asp.net core + mysql + ef core + linux 以前开发网站是针对windows平台,在iis上部署.由于这次需求的目标服务器是linux系统,就尝试用跨平台的.NET ...

  3. JavaScript星级评分

    事件onmouseover <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...

  4. JMS ActiveMQ案例

    创建一个web工程 导入ActiveMQ依赖的jar包  activemq-all-5.9.jar 写一个生产者(send)servlet package com.sun.jms;import jav ...

  5. IntelliJ IDEA中类似Eclipse自动补全变量名称和属性名称的快捷键

    IntelliJ IDEA 默认快捷键模式下 自动补全变量名称 : Ctrl + Alt + v 自动补全属性名称 : Ctrl + Alt + f

  6. 移动开发meta集合【精】

    以下是开发中经常用到的meta标签 1.移动webAPP的Meta 用法: <meta content="width=device-width, initial-scale=1.0, ...

  7. php 语言特点

    PS:绝大多数用php的企业/ 项目 活不到雇佣得起月薪35k以上的php程序员那一天,也是php码农在10年经验的时候普遍不如java程序员的原因之一. PS2: 由于薪资提升太快,很多php码农跳 ...

  8. 原生javascript扫雷游戏

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. one hot encoding

    转自:http://blog.sina.com.cn/s/blog_5252f6ca0102uy47.html 问题由来 在很多机器学习任务中,特征并不总是连续值,而有可能是分类值. 例如,考虑一下的 ...

  10. http协议的状态码 403 404 301 302 200 500 502 504 报错显示

    在网站建设的实际应用中,容易出现很多小小的失误,就像MySQL当初优化不到位,影响整体网站的浏览效果一样,其实,网站的常规http状态码的表现也是一样,Google无法验证网站几种解决办法,提及到由于 ...