gpt4 book ai didi

c++ - 动态内存和 "ordinary"内存的区别

转载 作者:IT王子 更新时间:2023-10-28 23:32:20 24 4
gpt4 key购买 nike

使用 new 分配的内存之间有哪些技术差异?通过简单的变量声明分配的运算符和内存,例如 int var ? c++ 是否有任何形式的自动内存管理?

特别是,我有几个问题。首先,因为使用动态内存你必须声明一个指针来存储你使用的实际内存的地址,动态内存不是使用更多的内存吗?除非你声明一个数组,否则我不明白为什么指针是必要的。

其次,如果我要创建一个像这样的简单函数:

int myfunc() { int x = 2; int y = 3; return x+y; }


...调用它,函数分配的内存会在其存在范围结束后立即释放吗?动态内存呢?

最佳答案

注:这个答案太长了。有时间我会删减的。同时,如果您能想到有用的编辑,请发表评论。

为了回答您的问题,我们首先需要定义两个名为 的内存区域。堆栈 .

堆栈

把堆栈想象成一堆盒子。每个框代表一个函数的执行。一开始,当main被称为,地板上有一个盒子。您定义的任何局部变量都在该框中。

一个简单的例子

int main(int argc, char * argv[])
{
int a = 3;
int b = 4;
return a + b;
}

在本例中,您在地板上有一个带有变量 argc 的盒子。 (整数), argv (指向字符数组的指针), a (整数)和 b (一个整数)。

一盒以上
int main(int argc, char * argv[])
{
int a = 3;
int b = 4;
return do_stuff(a, b);
}

int do_stuff(int a, int b)
{
int c = a + b;
c++;
return c;
}

现在,您在地板上有一个盒子(用于 main )和 argc , argv , a , 和 b .在那个盒子的顶部,你有另一个盒子(用于 do_stuff )和 a , b , 和 c .

这个例子说明了两个有趣的效果。
  • 您可能知道,ab是按值传递的。这就是为什么在 do_stuff 的框中有这些变量的拷贝的原因。 .
  • 请注意,您不必freedelete或这些变量的任何东西。当您的函数返回时,该函数的框被销毁。

  • 盒子溢出
        int main(int argc, char * argv[])
    {
    int a = 3;
    int b = 4;
    return do_stuff(a, b);
    }

    int do_stuff(int a, int b)
    {
    return do_stuff(a, b);
    }

    在这里,您在地板上有一个盒子(用于 main,和以前一样)。然后,您有一个带有 do_stuff 的盒子(用于 a )和 b .然后,您有另一个盒子(用于 do_stuff 调用自身),再次使用 ab .然后是另一个。很快,您就会遇到堆栈溢出。

    堆栈总结

    将堆栈视为一堆盒子。每个框代表一个正在执行的函数,该框包含在该函数中定义的局部变量。当函数返回时,该框被销毁。

    更多技术内容
  • 每个“盒子”被正式称为堆栈帧。
  • 有没有注意到您的变量如何具有“随机”默认值?当旧的堆栈帧被“破坏”时,它就不再相关了。它不会被归零或类似的东西。下一次堆栈帧使用该部分内存时,您会在局部变量中看到旧堆栈帧的位。



  • 这就是动态内存分配发挥作用的地方。

    把堆想象成一片无尽的绿色内存草地。当您调用 mallocnew ,在堆中分配了一 block 内存。您将获得一个访问该内存块的指针。
    int main(int argc, char * argv[])
    {
    int * a = new int;
    return *a;
    }

    在这里,在堆上分配了一个新整数的内存。你得到一个名为 a 的指针那指向那个内存。
  • a是一个局部变量,所以它在 main 中的“盒子”

  • 动态内存分配的基本原理

    当然,使用动态分配的内存似乎在这里和那里浪费了几个字节用于指针。但是,有些事情如果没有动态内存分配,您就无法(轻松)做到。

    返回一个数组
    int main(int argc, char * argv[])
    {
    int * intarray = create_array();
    return intarray[0];
    }

    int * create_array()
    {
    int intarray[5];
    intarray[0] = 0;
    return intarray;
    }

    这里会发生什么?您在 create_array 中“返回一个数组” .实际上,您返回了一个指针,该指针仅指向 create_array 的一部分。包含数组的“盒子”。当 create_array 时会发生什么返回?它的盒子被破坏了,你可以预料到你的阵列随时都会损坏。

    相反,使用动态分配的内存。
    int main(int argc, char * argv[])
    {
    int * intarray = create_array();
    int return_value = intarray[0];
    delete[] intarray;
    return return_value;
    }

    int * create_array()
    {
    int * intarray = new int[5];
    intarray[0] = 0;
    return intarray;
    }

    因为函数返回不会修改堆,你宝贵的 intarray毫发无损地逃脱。记得要 delete[]不过在你完成之后。

    关于c++ - 动态内存和 "ordinary"内存的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1021138/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com