-4

可能重复:
动态内存和“普通”内存之间的差异

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

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

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

4

6 回答 6

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.

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

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

在这种情况下,您的程序可以遍历文件,计算整数的数量,然后动态创建正确大小的数组。然后您再次传递文件,将整数读取到新数组中。

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

希望这可以帮助。

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

于 2012-04-19T12:40:09.330 回答
3

当你有:

char* p;

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

但是当你这样做时:

p = new char[100];

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

您负责释放堆上分配的内存:

delete[] p;

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

于 2012-04-19T12:36:18.360 回答
2

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

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

{
    int i;
    int *p = &i;
}
于 2012-04-19T12:32:11.317 回答
2

动态内存是程序员必须明确请求的内存,而不是在堆栈上自动分配。

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

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

int ar[5];

但是,如果你有 10 个元素,那么你不能这样做,解决方案是动态分配内存;

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

也就是说,必须释放所有动态分配的东西(在 C++ 中使用删除)

delete i_p;

但是,通常最好在可能的情况下对动态数组使用包装器,例如 std::vector

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

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

于 2012-04-19T12:34:35.277 回答
2

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

于 2012-04-19T12:34:35.360 回答
2

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

于 2012-04-19T12:37:16.120 回答