C++中4种管理数据内存的方式总结

 更新时间:2022年09月23日 16:34:37   作者:UestcXiye  
根据用于分配内存的方法,C++中有3中管理数据内存的方式:自动存储、静态存储和动态存储。在存在时间的长短方面,以这三种方式分配的数据对象各不相同。下面简要介绍这三种类型

根据用于分配内存的方法,C++中有3中管理数据内存的方式:自动存储、静态存储和动态存储(有时也叫做自由存储空间或堆)。在存在时间的长短方面,以这三种方式分配的数据对象各不相同。下面简要介绍这三种类型。

注:C++11中新增了第四种类型——线程存储

C++的4种管理数据内存的方式

自动存储

在函数内部定义的常规变量使用自动存储空间,被称为自动变量(automatic variable),这意味着它们在所属的函数被调用时自动产生,在该函数结束时消亡。例如,当在一个自定义的函数getname()中定义了一个temp数组时,temp数组仅当getname()函数活动时存在。当成许控制权回到main()时,temp使用的内存将自动被释放。如果getname()返回temp的地址,则main()中的name指针指向的内存将很快得到重新使用。这就是在getname()中使用new的原因之一。

实际上,自动变量是一个局部变量,其作用域为包含它的代码块。代码块是被包含在花括号中的一段代码。

自动变量通常存储在栈中。这意味着执行代码块时,其中的变量将依次加入到栈中,而在离开代码块时,将按相反的顺序释放着些变量,着被称为后进先出(LIFO)。因此,在程序执行过程中,栈将不断地增大和缩小。

静态存储

静态存储是整个程序执行期间都存在的存储方式。是变量称为静态的方式有两种:一种是在函数外面定义它;另一种是在声明变量时使用关键字statis:

static double fee = 56.50;

在K&R C中,只能初始化静态数组和静态结构,而C++ Release2.0(及后续版本)和ASNI C中,也可以初始化自动数组和自动结构。

注:自动存储和静态存储关键在于:这些方法严格地限制了变量的寿命。变量可能存在于程序的整个生命周期(静态变量),也可能只是在特定函数被执行时存在(自动变量)。

动态存储

new和delete运算符提供了一种比自动变量和静态变量更灵活的方法。它们管理了一个内存池,这在C++中被称为自由存储空间(free store)或堆(heap)。该内存池同用于静态变量和自动变量的内存是分开的。new和delete让您能够在一个函数中分配内存,而在另一个函数中释放它。因此,数据的声明周期不完全收程序或函数的生命时间控制。与使用常规变量相比,使用new和delete让程序员对程序如何使用内存有更大的控制权。然而,内存管理也更复杂了。在栈中,自动添加和删除机制使得占用的内存总是连续的,单new和delete的相互影响可能导致占用的自由存储区不连续,这使得跟踪新分配内存的位置更困难。

线程存储

在多线程程序中,所有线程共享程序中的变量。Linux有一全局变量,所有线程都可以使用它,改变它的值。如果每个线程希望能单独拥有它,那么就需要使用线程存储了。表面上看起来这是一个全局变量,所有线程都可以使用它,但它的值在每一个线程中又是单独存储的。

线程存储的具体用法:

1.创建一个类型为pthread_key_t类型的变量。

2.调用pthread_key_create()来创建该变量,该函数有两个参数,第一个参数就是上面声明的 pthread_key_t变量,第二个参数是一个清理函数,用来在线程释放该线程存储的时候被调用,该函数指针可以设成NULL,这样系统将调用默认的清理函数;

3.当线程中需要存储特殊值的时候,可以调用pthread_setspcific(),该函数有两个参数,第一个为前面声明的pthread_key_t变量,第二个为void*变量,这样可以存储任何类型的值;

4.如果需要取出所存储的值,调用pthread_getspecific(),该函数的参数为前面提到的 pthread_key_t变量,该函数返回void*类型的值;

5.注销使用pthread_key_delete()函数,该函数并不检查当前是否有线程正在使用,也不会调用清理函数,而只是释放以供下一次调用pthread_key_create()使用。

下面是前面提到的函数原型:

int pthread_setspecific(pthread_key_t key, const void *value);
void* pthread_getspecific(pthread_key_t key);
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
int pthread_key_delete(pthread_key_t *key);

线程存储例子:

#include <pthread.h>
#include <stdio.h>


static pthread_key_t thread_key;

void* thread_function(void* args)
{
    pthread_t spid = pthread_self();

    pthread_setspecific(thread_key, (void *)spid);

    pthread_t gpid = (pthread_t)pthread_getspecific(thread_key);

    printf("set: %lu, get: %lu, %s\n", spid, gpid, (spid == gpid ? "equal":"not equal"));

    return NULL;
}

int main(int argc, char** argv)
{
    int i;
    pthread_t threads[5];

    pthread_key_create(&thread_key, NULL);

    for (i = 0; i < 5; ++i) {
        pthread_create(&(threads[i]), NULL, thread_function, NULL);
    }

    for (i = 0; i < 5; ++i) {
        pthread_join(threads[i], NULL);
    }

    pthread_key_delete(thread_key);

    return 0;
}

栈、堆、内存泄漏

如果使用new在自由存储空间(或堆)上创建变量后,没有调用delete。会发生什么?

即使包含指针的内存由于作用域规则和对象生命周期的原因而被释放,在自由存储空间上动态分配的变量或结构依然存在。

实际上将会无法访问自由存储空间的结构,因为指向这些内存的指针无效。

这将导致内存泄露,被泄漏的内存在程序的整个生命周期将不可使用,这些内存被分配,但无法被使用。

到此这篇关于C++中4种管理数据内存的方式总结的文章就介绍到这了,更多相关C++数据内存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++线程之thread详解

    C++线程之thread详解

    这篇文章主要为大家详细介绍了C++线程中的thread,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • Qt实现Flappy Bird游戏

    Qt实现Flappy Bird游戏

    这篇文章主要为大家详细介绍了Qt实现Flappy Bird游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • C语言编程数据结构线性表之顺序表和链表原理分析

    C语言编程数据结构线性表之顺序表和链表原理分析

    本篇文章是C语言编程篇主要为大家介绍了C语言编程中的数据结构线性表,文中附含丰富的图文示例代码为大家详解了线性表中的顺序表和链表,有需要的朋友可以借鉴参考下
    2021-09-09
  • 基于C语言实现的贪吃蛇游戏完整实例代码

    基于C语言实现的贪吃蛇游戏完整实例代码

    这篇文章主要介绍了基于C语言实现的贪吃蛇游戏完整实例代码,对于学习游戏开发的朋友有一定的借鉴价值,需要的朋友可以参考下
    2014-08-08
  • C++运算符重载图文详解

    C++运算符重载图文详解

    运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的
    2021-09-09
  • C++ 右值引用与 const 关键字详解

    C++ 右值引用与 const 关键字详解

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,const关键字是一种修饰符,这篇文章主要介绍了C++ 右值引用与 const 关键字,需要的朋友可以参考下
    2022-10-10
  • VisualStudio2019配置OpenCV的详细过程

    VisualStudio2019配置OpenCV的详细过程

    这篇文章主要介绍了VisualStudio2019配置OpenCV,配置系统环境找到高级系统设置等一系列操作,本文分步骤通过图文并茂的形式给大家介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • C++设置超时时间的简单实现方法

    C++设置超时时间的简单实现方法

    这篇文章主要介绍了C++设置超时时间的简单实现方法,涉及系统函数setsockopt对套接口的操作,具有一定的实用价值,需要的朋友可以参考下
    2014-10-10
  • C++实现将数组中的值反转

    C++实现将数组中的值反转

    这里给大家分享的事一则C++实现将数组中的值反转的代码,取材自《C++程序设计》(梁勇著第三版367页),有需要的小伙伴可以参考下
    2016-05-05
  • C++基础学习之输入输出流详解

    C++基础学习之输入输出流详解

    C++是一种广泛应用的编程语言,其输入和输出是程序所必须的基本操作之一。本文将介绍C++中的输入和输出操作,包括输入输出流、文件输入输出等,希望对读者有所帮助
    2023-04-04

最新评论