C++ 动态内存分配

C++ 动态内存分配,c++,dynamic-memory-allocation,C++,Dynamic Memory Allocation,我对动态内存分配的概念有点困惑。 如果我们声明一个指针,比如说一个char指针,我们需要分配足够的内存空间 char* str = (char*)malloc(20*sizeof(char)); str = "This is a string"; 但这也会起作用 char* str = "This is a string"; 那么在哪种情况下我们必须分配内存空间 在第一个示例中,您从堆中动态分配了内存。它可以被修改,并且必须被释放。在第二个示例中,编译器静态分配内存,不能修改,也不能释放。对

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

char* str = (char*)malloc(20*sizeof(char));
str = "This is a string";
但这也会起作用

char* str = "This is a string";

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

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

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

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

char* str = (char*)malloc(20*sizeof(char)); 
str = "This is a string"; // memory leak
分配的地址将替换为新地址。 新地址是“这是一个字符串”的地址

你应该换第二个样品

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

因为“thisastring”是写保护区。

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

char* str = (char*)malloc(20*sizeof(char)); 
str = "This is a string"; // memory leak
分配的地址将替换为新地址。 新地址是“这是一个字符串”的地址

你应该换第二个样品

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

因为“thisastring”是写保护区。

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

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

我想补充一点,在第一个示例中,您可以通过将“This is a string”复制到
str
来避免内存泄漏,如下代码所示:

char* str = (char*)malloc(20*sizeof(char));
strcpy(str, "This is a string");
请注意,我所说的“可以”并不意味着你必须这样做。它只是增加了一个答案,为这个线程增加了价值。

我想补充一点,在第一个示例中,您可以通过将“thisastring”复制到
str
来避免内存泄漏,如下代码所示:

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

请注意,我所说的“可以”并不意味着你必须这样做。它只是增加了一个答案,为这个线程增加了价值。

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

首先,在内存中分配一个缓冲区,并将该内存的地址分配给
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*
进行此分配

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


在许多情况下,例如当您需要修改缓冲区时。换言之;当您需要指向不能是静态字符串常量的内容时。

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

首先,在内存中分配一个缓冲区,并将该内存的地址分配给
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*
进行此分配

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


在许多情况下,例如当您需要修改缓冲区时。换言之;当您需要指向不能是静态字符串常量的内容时。

大概是C++98代码段

char* str = (char*)malloc(20*sizeof(char));
str = "This is a string";
char* str = "This is a string";
执行以下操作:(1)分配20个字节,将指向该内存块的指针存储在
str
中;(2)将指向文本字符串的指针存储在
str
中。您现在无法引用先前分配的块,因此无法解除分配