什么是动态记忆?

时间:2012-04-19 12:28:54

标签: c++

  

可能重复:
  Differences between dynamic memory and “ordinary” memory

我正在阅读C ++教程,我不明白为什么需要声明动态内存,这就是教程所说的:

  

到目前为止,在我们所有的程序中,我们只有我们为变量声明的可用内存,在程序执行之前,所有变量的大小都要在源代码中确定。

然后它说我们必须使用new和delete运算符来使用动态内存。 但是,我似乎在声明指针时使用动态内存,例如char * p,我没有指定字符数组的长度。事实上,我认为当你使用指针时,你总是使用动态内存。不是吗? 我只是没有看到使用new运算符声明变量之间的区别。我真的不明白动态内存是什么。谁能解释一下这个?

6 个答案:

答案 0 :(得分:5)

  

我认为当你使用指针时,你总是使用动态   记忆。不是吗?

不,这不是真的,例如

int i;
int *p = &i; // uses a pointer to static memory, no dynamic memory.
  

然而,我似乎在声明指针时使用动态内存,   例如char * p,我没有指定数组的长度   字符

char[100] string;
char* p = &(string[0]);  // Same as above, no dynamic memory.

当您无法确定数据结构需要多大时,您需要动态内存。

假设你要从文件中读取一些int并将它们存储在内存中。你不知道你需要多少in。你可以选择一个100的数字,但是如果有101则你的程序会中断。你可以选择100,000希望这已经足够了,但是如果文件中只有10个则浪费资源,而且如果有100,001个整数则会中断文件。

在这种情况下,您的程序可以遍历文件,计算整数,然后动态创建一个正确大小的数组。然后你第二次将文件读入你的新数组。

静态v的动态记忆
静态内存是静态的,因为一旦程序被编译就无法更改,它是静态的。您在函数中声明的变量,在类/结构上声明的成员是静态的。当每个方法被调用时,编译器会准确计算每个方法需要多少个 动态内存是内存的“池”,可以在运行时根据需要提供给您的程序。 编译器只知道它需要分配一些(可能是未知的)内存量,并将该内存释放回动态内存池。

希望这有帮助。

P.S。是的,有更有效的方法可以将未知数量的项目存入内存,但这是最简单的解释

答案 1 :(得分:3)

当你有:

char* p;

p是指向char的类型指针的变量,p存储在堆栈中,并且您没有分配任何动态内存。

但是当你这样做时:

p = new char[100];

您已经分配了大小为100 * sizeof(char)的动态内存(堆)的一部分。

您有责任在堆上释放已分配的内存:

delete[] p;

您不需要从堆栈中清除变量 - 变量超出范围后会自动删除它们。在此示例中,p将在超出其范围时从堆栈中删除。

答案 2 :(得分:2)

  

事实上,我认为当你使用指针时,你总是使用动态内存。不是吗?

没有。这是一个指向堆栈分配(“自动”)内存的指针:

{
    int i;
    int *p = &i;
}

答案 3 :(得分:2)

动态内存是程序员必须明确请求的内存,因为它反对在堆栈上自动分配。

动态内存有很多优点,例如在堆栈帧(函数调用)之间保持不变,并且可以有不同的大小。

在堆栈上,一个数组有一定的大小:

int ar[5];

但是,如果你有10个元素则无法做到,那么解决方案就是动态分配内存;

size_t sz;
std::cin >> sz;
int *i_p=new int[sz];

表示必须释放动态分配的所有内容(在C ++中使用delete)

delete i_p;

然而,在可能的情况下,尽可能将包装器用于动态数组,例如std :: vector

size_t sz;
std::cin >> sz;
std::vector<int> vect(sz);

这将自动管理内存并为阵列提供有用的界面。

答案 4 :(得分:2)

假设您想要从用户读取未知数量的整数。例如,您可以声明int numbers[100],询问用户有多少数字(假设这是存储在变量n中),如果他输入的数字大于100,您将别无选择但报告错误。或者,您可以编写int *numbers = new int[n]并为所有数字分配足够的空间。

答案 5 :(得分:2)

c ++中的动态内存是使用new运算符在操作系统堆中分配的内存。当您需要分配太大且无法在堆栈中分配的对象时,或者当您具有多线程环境并且需要共享在不同线程之间的一个线程中分配的内存时,您需要动态内存。指针并不意味着您使用动态内存指针也可以包含与堆栈中的对象相关的堆栈地址。