深入理解C语言结构体成员变量内存分配

简介: 深入理解C语言结构体成员变量内存分配


1 问题描述

在学习C语言的时候,我们都会频繁的接触到结构体,使用结构体定义新的数据类型,从而更加方便的存储数据。但是在使用结构体的时候,有些问题会经常会困扰我们,如下所示:


第一种结构体定义:

struct school{

   char address[100];

   char name[30];

};


第二种结构体定义:

struct school_other{

   char *address;

   char *name;

};

以上两种结构体的定义有什么区别?我们在使用的时候需要注意什么?


本文将和大家一起来深入的探讨这个问题。


2 分析问题

很多时候对于大家来说,最重要的不是得到问题的答案,而是学会别人是如何分析问题的,这种解决问题的思路对于大家来说才是最重要的,也是最精彩的地方。


C语言中定义的任何一个变量,最终都会从你的内存条上拿走相应的内存空间,如定义了一个int a;那么四个字节的空间就给a这个变量了。既然如此,我们很好奇,上述两种类型的结构体,分别占用了多大的内存空间呢?为了解决这个问题,我们编写了以下的程序:

这个程序应该很简单,相信各位同学都能看懂,首先定义了两个结构体类型struct school和struct school_other,然后在main函数中定义了两个变量,最后使用sizeof()函数获得变量的内存空间大小。


程序的输出结果如下:


这种输出结果不知是大家意料之中还是意料之外呢?无论是哪种情况,我们一起来分析分析。


如果要我们去计算第一个结构体的内存占用空间,你该如何去计算?

struct school{

   char address[100];

   char name[30];

};


由于sizeof(char)==1得到每一个字符型数据占用的空间大小是一个字节,因此上述结构体占用的空间应该是:1 Byte * 100 + 1 Byte * 30 = 130 Byte,这个答案和输出的结果是一致的。


按照同样的方式我们去计算另外一个结构体的内存占用空间:

struct school_other{

   char *address;

   char *name;

};


由于sizeof(char *) == 8得到每一个指针类型的数据占用的空间是八个字节,因此上述结构体占用的空间应该是:8 Byte * 1 + 8 Byte * 1 = 16 Byte,这个答案也和输出结果一致。


为什么要花这么多的篇幅去介绍结构体类型空间大小呢?

貌似和主题无关,其实正是深入理解主题的核心所在。本文定义一个school结构体的目的在于通过school结构体能够保存某个学校的地址和名称,而地址和名称都是字符数组类型,这种类型可以保存多个字符。

struct school这种结构体类型为其成员变量address和name分配了大小分别为100和30的内存空间,有了内存空间,因此可以直接使用。


而struct school_other这种结构体类型并没有为其成员变量分配内存空间,因此在使用之前必须对其分配,才可以为其赋值。


上述问题,其实可以进一步简化成:

char address[100];

char* address_other;


这两种变量大家在使用时,应该注意什么?


address变量已经有了100个字节的内存空间,因此可以直接对其进行赋值,而address_other只是一个指针即只是一个内存地址,而这个地址是多少并未知晓,因此在使用之前,务必要分配内存空间,然后才能使用。


3 总结

本文介绍了结构体指针类型的成员变量和数组类型的成员变量的区别,以及在使用时应该注意的问题,帮助大家更好的理解内存分配。

目录
相关文章
|
8天前
|
存储 Java 程序员
结构体和类的内存管理方式在不同编程语言中的表现有何异同?
不同编程语言中结构体和类的内存管理方式既有相似之处,又有各自的特点。了解这些异同点有助于开发者在不同的编程语言中更有效地使用结构体和类来进行编程,合理地管理内存,提高程序的性能和可靠性。
16 3
|
10天前
|
存储 缓存 Java
结构体和类在内存管理方面的差异对程序性能有何影响?
【10月更文挑战第30天】结构体和类在内存管理方面的差异对程序性能有着重要的影响。在实际编程中,需要根据具体的应用场景和性能要求,合理地选择使用结构体或类,以优化程序的性能和内存使用效率。
|
10天前
|
存储 缓存 算法
结构体和类在内存管理方面有哪些具体差异?
【10月更文挑战第30天】结构体和类在内存管理方面的差异决定了它们在不同的应用场景下各有优劣。在实际编程中,需要根据具体的需求和性能要求来合理选择使用结构体还是类。
|
21天前
|
存储 C语言
如何在 C 语言中实现结构体的深拷贝
在C语言中实现结构体的深拷贝,需要手动分配内存并逐个复制成员变量,确保新结构体与原结构体完全独立,避免浅拷贝导致的数据共享问题。具体方法包括使用 `malloc` 分配内存和 `memcpy` 或手动赋值。
30 10
|
20天前
|
C语言
【c语言】动态内存管理
本文介绍了C语言中的动态内存管理,包括其必要性及相关的四个函数:`malloc`、``calloc``、`realloc`和`free`。`malloc`用于申请内存,`calloc`申请并初始化内存,`realloc`调整内存大小,`free`释放内存。文章还列举了常见的动态内存管理错误,如空指针解引用、越界访问、错误释放等,并提供了示例代码帮助理解。
31 3
|
21天前
|
存储 大数据 编译器
C语言:结构体对齐规则
C语言中,结构体对齐规则是指编译器为了提高数据访问效率,会根据成员变量的类型对结构体中的成员进行内存对齐。通常遵循编译器默认的对齐方式或使用特定的对齐指令来优化结构体布局,以减少内存浪费并提升性能。
|
25天前
|
编译器 C语言
共用体和结构体在 C 语言中的优先级是怎样的
在C语言中,共用体(union)和结构体(struct)的优先级相同,它们都是用户自定义的数据类型,用于组合不同类型的数据。但是,共用体中的所有成员共享同一段内存,而结构体中的成员各自占用独立的内存空间。
|
25天前
|
存储 C语言
C语言:结构体与共用体的区别
C语言中,结构体(struct)和共用体(union)都用于组合不同类型的数据,但使用方式不同。结构体为每个成员分配独立的内存空间,而共用体的所有成员共享同一段内存,节省空间但需谨慎使用。
|
30天前
|
编译器 C语言 C++
C语言结构体
C语言结构体
25 5
|
22天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
19 0