C++ 动态内存分配
我对动态内存分配的概念有点困惑。 如果我们声明一个指针,比如说一个char指针,我们需要分配足够的内存空间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* 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
中。您现在无法引用先前分配的块,因此无法解除分配