动态内存分配

时间:2011-06-20 08:42:57

标签: c++ dynamic-memory-allocation

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

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

但这也有效。

char* str = "This is a string";

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

7 个答案:

答案 0 :(得分:7)

在第一个示例中,您有内存泄漏

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";  

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

答案 1 :(得分:4)

可能是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";

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

而不是这种愚蠢,请使用标准库中的str,并在代码中自由地使用std::string

干杯&第h。,

答案 2 :(得分:2)

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

答案 3 :(得分:2)

分配给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";

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

答案 4 :(得分:1)

在第一个例子中,你只是做错了。您在堆上分配动态内存并让str指向它。然后你只是让str指向一个字符串文字,并且分配的内存被泄露(你没有将字符串复制到已分配的内存中,你只需更改地址str指向的地址,你就会有在第一个例子中使用strcpy

答案 5 :(得分:1)

我想添加到Alexey Malistov's Answer,在第一个示例中通过将“This is a string”复制到str来避免内存泄漏,如下面的代码所示:

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

请注意,可以我并不是说你。它只是增加了一个为这个线程增加价值的答案。

答案 6 :(得分:1)

字符串文字是该语言的一个特例。让我们仔细看看您的代码,以便更好地理解这一点:

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

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

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

str = "This is a string";

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

这解释了为什么这种方法很有效:

char* str = "This is a string";

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

  

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

在许多情况下,例如当您需要修改缓冲区时。换一种说法;当你需要指向一些不能成为静态字符串常量的东西时。