本文介绍: 人生如路,要有耐心。要想快乐生活,就要学会一切随缘,不强求不可得,不执着已失去,淡定悠然,随遇而安。烦恼好比心中的黑暗,只有点亮随缘的心灯,才能驱散黑暗,照亮人生。—-小新

         人生如路,要有耐心。要想快乐生活,就要学会一切随缘,不强求不可得,不执着已失去,淡定悠然,随遇而安。烦恼好比心中的黑暗,只有点亮随缘的心灯,才能驱散黑暗,照亮人生。        

                                                                                                                                          —-小新

一.内存分配方式

     1.全局存储区域静态存储区)

        这种分配方式编译器自动完成,在程序编译时就已经分配内存例如全局变量static变量就是静态存储区域进行分配的。这种方式的优点是内存空间大小固定,且在整个程序运行期间都存在,直到程序运行结束时才被释放。

int global_var = 10; // 全局变量编译时就已经分配内存,整个程序运行期间都存在

     2.在栈上分配

        这种方式也由编译器自动完成。当函数调用时,函数内部局部变量可以在栈上创建。当函数执行结束时,这些存储单元会被自动释放。这种方式的优点是分配和释放速度快,但是分配内存容量有限

void func() { // 函数执行时在栈上创建局部变量执行结束时自动释放  
    int local_var = 20; // 局部变量在栈上分配内存  
    // 函数执行结束,局部变量自动释放  
}

      3.从堆上分配

        这种方式称为动态内存分配,它由程序员手动完成程序员使用内存分配函数(如mallocnew)来申请任意大小内存使用完之后再由程序员自己负责使用内存释放函数(如freedelete)来释放内存。这种方式的优点是可以根据需要动态申请和释放内存,但是需要程序员手动管理,容易造成内存泄漏

int* ptr = NULL; // 指向动态内存的指针  
ptr = (int*)malloc(sizeof(int)); // 在堆上分配内存,如果分配失败返回NULL  
if (ptr == NULL) {  
    printf("Memory allocation failed!n");  
    return -1; // 返回错误代码  
}  
*ptr = 30; // 写入动态内存的值  
printf("The value of ptr is: %pn", ptr); // 输出动态内存的地址  
printf("The value of *ptr is: %dn", *ptr); // 输出动态内存的值  
free(ptr); // 释放动态内存,防止内存泄漏

二.堆和栈的区别

        1.申请方式

                栈:系统自动分配;

                堆:人为申请开辟。

        2.空间大小

                栈:获得的空间较小,一般为几MB;

                堆:获得的空间较大。

        3.申请效率

                栈:由系统自动分配,速度较快;

                堆:要依靠malloc等API申请,申请的过程比较复杂速度比较慢。

        4.存储内容

                栈:函数调用时,函数调用语句的下一条执行语句地址第一个进栈然后函数各个参数进栈,其中静态变量是不入栈的,静态变量存放数据段;

                堆:一般是在头部一个字节存放堆的大小,堆中的具体内容是人为安排。

        5.底层

                栈:连续的空间

                堆:不连续的空间,堆可能有许多内存碎片

 

三.栈在c语言中的作用

  1.保存局部变量函数参数

        在函数调用过程中,局部变量函数参数会被存储在栈上。当函数执行结束后,这些变量参数会被自动释放,从而为后续的函数调用腾出空间。

  2.实现函数调用返回

        在C语言中,函数调用时会在栈上为其分配一个新的栈帧,包含函数的局部变量参数返回地址。当函数执行结束时,会从栈上弹出该栈帧,回到函数调用前的状态

  3.实现递归

        递归函数会在每次递归调用时在栈上分配一个新的栈帧,从而实现了函数的嵌套调用。当递归结束时,会逐层返回,逐个释放栈帧。

  4.实现动态内存分配

        C语言中的动态内存分配通常使用堆来实现,但栈上也存在一种特殊的动态内存分配方式,即使用alloca函数在栈上分配内存。这种方式比堆分配要快,但可能会导致栈溢出或内存碎片问题

 四.内存泄漏

        简单来说就是申请了内存,不使用之后并没有释放内存,或者说,指向申请的内存的指针突然又去指向别的地方,导致找不到申请的内存,

  (1)影响

        随着程序运行时间越长,占用内存越多,最终用完内存,导致系统崩溃

  (2)减少内存泄漏

        1.良好的编码习惯,使用内存分配的函数,一但使用完毕之后就要记得使用对应的函数是否掉;

        2.将分配的内存的指针链表的形式自行管理,使用之后从链表删除程序结束时可以检查链表

        3.使用智能指针

 五.字节对齐问题

        数据在内存中的存储位置(即地址)是按照某个特定的规则进行对齐的。这个规则通常由计算机硬件操作系统定义对齐的目的是为了提高内存的访问效率,因为CPU通常一次只能读取固定大小的内存,如果数据没有对齐,就需要多次读取才能获取完整的数据。

        字节对齐问题通常出现在低级编程语言如C/C++中,因为这些语言直接操作内存,需要程序员自己管理数据的存储。而在高级语言中,编译器通常会自动处理字节对齐问题

解决字节对齐问题方法通常包括以下几种

  1.数据类型对齐

        在定义数据结构变量时,可以使用特定的数据类型来保证字节对齐。例如,在C++中,可以使用alignas关键字指定数据的对齐方式。

  2.填充

        在某些情况下,可以在数据之间插入填充字节,以保证数据的对齐。这种方法通常用于处理多个内存地址数据结构

  3.使用特定的编译器指令属性

        某些编译器提供了特定的指令属性控制字节对齐的方式。例如,在C++中,可以使用#pragma pack指令控制数据结构的对齐方式。

        总之,字节对齐问题一个与内存管理和数据访问效率密切相关问题。在编写低级语言处理性能敏感代码时,需要特别关注字节对齐问题

原文地址:https://blog.csdn.net/weixin_66634995/article/details/134720952

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_41196.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注