一、有关结构体的内存处理包括,结构体指针和结构体成员指针的内存分配、结构体成员的数据对齐、结构体的内存释放

    1、定义:与自定义数据类型(结构体)有关的内存分配、大小和释放问题

    2、特征:

      1)、用内存分配函数malloc()和释放free()和长度测试strlen()函数完成相关的内存操作工作;

      2)、为不含有指针成员结构体分配内存时,与普通类型分配的方式是一样的;

      3)、释放不含有指针成员结构体内存时,与普通内存释放也是一样的;

      4)、为含有指针成员结构体分配内存时,必须先分配整个结构体的内存,再申请结构体指针成员的内存;

      5)、释放含有指针成员结构体内存时,必须先释放所有结构体指针成员的内存,再释放结构体内存;

      6)、结构体需要的内存大小和实际分配的大小可能会有所偏差;

      7)、使用结构体指针访问是需要特别留心,尽量避免访问到结构体成员中的额外空白内存;

      8)、释放不含有指针成员结构体内存时,与普通内存释放也是一样的;

      9)、为含有指针成员结构体分配内存时,必须先分配整个结构体的内存,再申请结构体指针成员的内存;

      10)、释放含有指针成员结构体内存时,必须先释放所有结构体指针成员的内存,再释放结构体内存;

    3、结构体的内存分配应用:

      1)、结构体指针需要手工分配内存

      2)、结构体中还有指针成员需要手工分配内存

      3)、必须先分配结构体内存,再分配成员内存

  #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h> int main(int argc, char **argv)
{
typedef struct _student{
char *name;
char *address;
int age;
short id;
bool sex;
} Student; Student stu;
stu.name = (char *)malloc(strlen("zhangsan") + );
strcpy(stu.name, "zhangsan");
stu.address = (char *)malloc(strlen("jiangxijiujiang") + );
strcpy(stu.name, "jiangxijiujiang");
stu.age = ;
stu.id = ;
stu.sex = true; printf("stu inf: ");
printf("stu.name: %s\n", stu.name);
printf("stu.address: %s\n", stu.address);
printf("stu.age: %d\n", stu.age);
printf("stu.id: %d\n", stu.id);
printf("stu.sex: %d\n", stu.sex);
printf("\n"); Student *ptrStu;
ptrStu = (Student *)malloc(sizeof(Student));
ptrStu->name = (char *)malloc(strlen("lisi") + );
strcpy(ptrStu->name, "lisi");
ptrStu->address = (char *)malloc(strlen("jiangxishangrao") + );
strcpy(ptrStu->address, "jiangxishangrao");
ptrStu->age = ;
ptrStu->id = ;
ptrStu->sex = false; printf("ptrStu inf: ");
printf("ptrStu.name: %s\n", ptrStu->name);
printf("ptrStu.address: %s\n", ptrStu->address);
printf("ptrStu.age: %d\n", ptrStu->age);
printf("ptrStu.id: %d\n", ptrStu->id);
printf("ptrStu.sex: %d\n", ptrStu->sex);
printf("\n");
free(ptrStu->name);
free(ptrStu->address);
free(ptrStu); return ;
}

  代码说明:

      1)、第7-14行定义结构体Student,结构体中有指针成员变量;

      2)、第16行声明普通结构体变量stu;

      3)、第17行为结构体变量stu的指针成员变量name申请内存空间,第19行为address申请内存空间;

      4)、第18行为结构体变量stu的指针成员变量name复制内容,使用字符串复制操作实现,第20行为address复制内容;

      5)、第33行声明指针结构体变量ptrStu;

      6)、第34行为指针结构体变量ptrStu申请内存空间;

      7)、第35行为结构体变量ptrStu的指针成员变量name申请内存空间,第37行为address申请内存空间;

      8)、第36行为结构体变量ptrStu的指针成员变量name复制内容,使用字符串复制操作实现,第38行为address复制内容;

      9)、结构体指针变量的成员访问符号,一般使用ptrStu->name,偶尔见到有人使用(*ptrStu).name,建议使用前者;

    4、结构体的内存大小和对齐应用:

      1)、结构体中成员变量的大小影响结构体的大小

      2)、结构体中成员变量的类型影响结构体的大小

      3)、结构体中成员变量的声明顺序影响结构体的大小

  #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h> int main(int argc, char **argv)
{
typedef struct _student1{
char *name;
char *address;
int age;
short id;
bool sex;
char se0;
} Student1; typedef struct _student2{
char *name;
char *address;
int age;
bool sex;
short id;
char se0;
} Student2; typedef struct _student3{
char se0;
char *name;
bool sex;
char *address;
int age;
short id;
} Student3; Student1 *ptrStu1;
printf("Student1 size: %d\n", sizeof(Student1));
printf("Student2 size: %d\n", sizeof(Student2));
printf("Student3 size: %d\n", sizeof(Student3)); return ;
}

  代码结果为:

Student1 size:
Student2 size:
Student3 size:

  代码说明:

      1)、Student1、Student2和Student3的成员类型及大小是完全一样;

      2)、Student1、Student2和Student3的成员声明的顺序不完全一样;

      3)、结构体大大小完全不一样;

      4)、name指针大小为8个字节,同样address为8个字节,age大小为4个字节,id为2个字节,sex为1个字节,se0为1个字节;

      5)、按照说明4完全成立,Student1和Student2和Student3大小应该都是24个字节;

      6)、结构体中成员变量间存在着内存对齐,基本规则就是下个成员的大小决定上个成员的内存结束位置,至少是下个成员大小的整数倍,最终大小是4或8的倍数;

      7)、结构体Student1中name:8, address : 8, age :4, id : 2, sex : 1, se0:1,共计24字节;

      8)、结构体Student2中name:8, address : 8, age :4, sex : 1,id : 2,  se0:1,共计32字节;

      9)、结构体Student3中se0:1,name:8, sex : 1,address : 8, age :4, id : 2, 共计40字节;

    5、结构体的内存释放应用:

      1)、参加3的应用部分

    6、结构体数组的应用:

      1)、声明数组时,指定数据类型为结构体类型即可

    7、位结构体的应用,主要应用于需要按位访问数据时,位结构更加方便与快捷:

      1)、声明结构体时,与其他结构体的声明方式完全相同;

      2)、结构体中的数据类型只能是unsigned或signed,当成员长度为1时,默认是unsigned;

      3)、位结构的成员变量的顺序是位排列的顺序; 

      4)、位结构的成员变量不能是指针或数组类型;

      5)、位结构的总长度是所有成员定义的位数之和,可以超过2个字节;

      6)、位结构的使用方法与其他结构使用方式一样,也可以与其他结构一起使用;

      7)、位结构变量可以是指针或数组变量

36深入理解C指针之---结构体的内存处理的更多相关文章

  1. 35深入理解C指针之---结构体基础

    一.结构体基础 1.定义:结构体大大加强了C的数据聚合能力,可以使得不同类型的数据进行结合 2.特征: 1).结构体可以使得不同类型的数据进行结合 2).结构体可以使用内置的数据类型,包括指针 3). ...

  2. 37深入理解C指针之---结构体与指针

    一.结构体与指针 1.结构体的高级初始化.结构体的销毁.结构体池的应用 2.特征: 1).为了避免含有指针成员的结构体指针的初始化复杂操作,将所有初始化动作使用函数封装: 2).封装函数主要实现内存的 ...

  3. c语言指针与结构体之内存动态分配

    struct dangdangtest { ]; ]; ]; int num; int bugnum; ]; ]; double RMB; }; void main2() { //struct dan ...

  4. 深入理解C指针之六:指针和结构体

    原文:深入理解C指针之六:指针和结构体 C的结构体可以用来表示数据结构的元素,比如链表的节点,指针是把这些元素连接到一起的纽带. 结构体增强了数组等集合的实用性,每个结构体可以包含多个字段.如果不用结 ...

  5. 结构体,内存,指针例题.DOC

    2015.1.30 递归函数:1.自身调用自己:2.要有结束条件!typedef 后面加分号:一般后面的重定义名加_,例如:typedef unsigned long int uint_16;结构体成 ...

  6. c语言指针与结构体

    #include <stdio.h> #include <stdlib.h> struct mydata { int num; ]; }; void main1() { /*i ...

  7. Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型

    Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...

  8. 【阅读笔记】《C程序员 从校园到职场》第七章 指针和结构体

    原文地址:让你提前认识软件开发(13):指针及结构体的使用 CSDN博客 https://blog.csdn.net/zhouzhaoxiong1227/article/details/2387299 ...

  9. C++ 利用指针和数组以及指针和结构体实现一个函数返回多个值

    C++ 利用指针和数组实现一个函数返回多个值demo1 #include <iostream> using namespace std; int* test(int,int,int); i ...

随机推荐

  1. 理解JS闭包的几个小实验

    学了JavaScript有一段时间了,但是对闭包还是不太理解,于是怀着心中的疑问做了几个小实验,终于有点明白了. 首先看一下MDN上的定义:闭包是函数和声明该函数的词法环境的组合. 简单来说,闭包是一 ...

  2. JavaScript中数组的使用

    ---恢复内容开始--- 创建数组 1,通过 var arr1 = [1,2,3] 2通过使用 var arr2 = new Array(1,2,3) 在这里创造的数组实际上都是一个对象,然后把对象的 ...

  3. Unity学习之路——C#相关

    1.C#数组数组定义 int[] number; float[] score; string[] names;动态初始化,借助new运算符为数组元素分配空间int[] Array = new int[ ...

  4. leetcode-15-basic-string

    58. Length of Last Word 解题思路: 从结尾向前搜索,空格之前的就是最后一个词了.写的时候我考虑了尾部有空格的情况.需要注意的是,测试用例中有" "的情况,此 ...

  5. linux学习-使用者身份切换

    在 Linux 系统当中还要作身份的变换?这是为啥?可能有底下几个原因啦! 使用一般账号:系统平日操作的好习惯 用较低权限启动系统服务 软件本身的限制 由于上述考虑,所以我们都是使用一般账号登入系统的 ...

  6. centos7 bond 和 网桥配置

    rhel7系统bond配置(更新版本):https://www.cnblogs.com/zhangjianghua/p/9119808.html Bonding的模式一共有7种: 1.mode=0(b ...

  7. bash脚本编写基础

    bash脚本编程     命令的堆砌     脚本程序:解释器解析执行     shell:交互式接口,编程环境         shell:能够提供一些内部命令,并且能通过PATH环境变量找到外部命 ...

  8. Android开发——减小APK大小

    0. 前言 APK的大小对APP的加载速度,使用内存大小和消耗功率多少有一定影响.如何减小APK的大小对于Android开发者是一个永恒的话题. 查阅了很多相关资料,并将其做了删减以及总结.本文原创, ...

  9. RQNOJ:PID30 / [stupid]愚蠢的矿工☆(树形背包)

    PID30 / [stupid]愚蠢的矿工☆ 背景 Stupid 家族得知在HYC家的后花园里的中央花坛处,向北走3步,向西走3步,再向北走3步,向东走3步,再向北走6步,向东走3步,向南走12步,再 ...

  10. hexo博客出现“Cannot GET/xxxx”的错误

    最近在github上搭了一个hexo博客系统,非常轻量级的,只需要几句nodejs命令就搭建完成了.我了解了一下,hexo博客是基于nodejs写的,采用ejs模板引擎编写页面. 因为默认的主题风格不 ...