动态内存分配

Dynamic Memory Allocation

本文关键字:分配 内存 动态      更新时间:2023-10-16

我对动态内存分配的概念有点困惑。如果我们声明一个指针,比如说char指针,我们需要分配足够的内存空间。

char* str = (char*)malloc(20*sizeof(char));
str = "This is a string";

但这也会奏效。

char* str = "This is a string";

那么,在哪种情况下,我们必须分配内存空间?

在第一个样本中,您有内存泄漏

char* str = (char*)malloc(20*sizeof(char)); 
str = "This is a string"; // memory leak

分配的地址将替换为新地址。新地址是"This is a string"的地址。

你们应该换第二个样品。

const char* str = "This is a string";  

因为"这是一个字符串"是写保护区。

可能是C++98代码片段

char* str = (char*)malloc(20*sizeof(char));
str = "This is a string";

执行以下操作:(1)分配20个字节,将指向该内存块的指针存储在str中;(2)将指向文字字符串的指针存储到str中。您现在无法引用先前分配的块,因此无法解除分配。您已经泄露了内存。

请注意,由于str已声明为char*,因此编译器实际上无法检测您是否尝试使用来修改文字。令人高兴的是,在C++0x中,这将不会编译。我真的很喜欢规则的改变!

代码片段

char* str = "This is a string";

在名为strchar*变量中存储一个指向字符串文字的指针,与第一个示例中一样,与该示例一样,它不会使用C++0x编译器进行编译。

例如,使用标准库中的std::string,并在整个代码中大量使用const,而不是这种愚蠢的做法。

干杯&hth。,

在第一个示例中,动态地从堆中分配内存。它可以被修改,而且必须被释放。在第二个示例中,编译器静态分配内存,并且不能修改内存,也不能释放内存。字符串文字必须使用const char*,而不是char*,以反映这一点并确保安全使用。

分配给char*变量会使其指向其他对象,那么,如果您立即忘记了内存,为什么要首先分配内存呢?这是内存泄漏。你可能是这个意思:

char* str = (char*)malloc(20*sizeof(char));
strcpy(str, "This is a string");
// ...
free(str);

这将把第二个字符串复制到第一个字符串。由于这是标记为C++的,您应该使用std::string:

#include <string>
std::string str = "This is a string";

不需要手动分配和释放内存,分配会按照您的想法进行。

字符串文字在该语言中是一种特殊情况。让我们仔细看看你的代码,更好地理解这一点:

首先,在内存中分配一个缓冲区,并将该内存的地址分配给str:

char* str = (char*)malloc(20*sizeof(char));

然后,为str指定一个字符串文字。这将覆盖str之前保存的内容,因此您将丢失动态分配的缓冲区,从而导致内存泄漏。如果您想修改分配的缓冲区,您可能需要在某个时刻取消引用str,如str[0] = 'A'; str[1] = '';中所示。

str = "This is a string";

那么,现在str的值是多少呢?编译器将所有字符串文字放在静态内存中,因此程序中每个字符串文字的生存期等于整个程序的生存期。该语句被编译为类似于str = (char*)0x1234的简单赋值,其中0x1234应该是编译器放置字符串文字的地址。

这就解释了为什么它能很好地工作:

char* str = "This is a string";

还请注意,静态内存在运行时不会更改,因此您应该使用const char*进行此分配。

那么,在哪种情况下,我们必须分配内存空间?

在许多情况下,例如需要修改缓冲区时。换句话说;当你需要指向一个不能是静态字符串常量的东西时。

我想添加到Alexey Malistov的Answer中,在第一个例子中,通过将"This is a string"复制到str,可以避免内存泄漏,如下代码所示:

char* str = (char*)malloc(20*sizeof(char));
strcpy(str, "This is a string");

请注意,可以我的意思不是你。它只是添加到一个答案中,为这个线程添加值。

在第一个例子中,您只是做错了一些事情。你在堆上分配动态内存,让str指向它。然后你只让str指向一个字符串文字,分配的内存就会泄漏(你不把字符串复制到分配的内存中,你只需要改变str指向的地址,在第一个例子中你必须使用strcpy)。