内存泄漏,指向文字的指针
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存泄漏,指向文字的指针相关的知识,希望对你有一定的参考价值。
我已经学会了不要让指针指向文字,因为它会导致内存泄漏。但是当我指定一个文字的指针时,它仍然指向与以前相同的地址:
unsigned maxlen = 20;
char* testpointer = new char[sizeof(char) * maxlen]; //Pointer points to RAM
cout << "&testpointer = " << &testpointer << endl;
strncpy(testpointer, "Happy Eastern", 13);
cout << "&testpointer = " << &testpointer << endl;
testpointer = "Merry Christmas"; // I know I shouldn't do this
cout << "&testpointer = " << &testpointer << endl;
我每次仍然得到相同的内存地址:
&testpointer = 0x28fc60
&testpointer = 0x28fc60
&testpointer = 0x28fc60
当我让指针指向文字时,地址不应该改变吗?我认为我用new分配的内存应该在RAM中,而文字应该在ROM中,它应该有不同的地址。我错了吗?
谢谢你,菲利普
你的cout
指令正在打印名为testpointer
的变量的地址。这是当前函数的堆栈帧中的某个位置。它与testpointer
的值无关,也与testpointer
指出的值无关。
此外,无论是谁告诉你你不应该让指针指向一个文字是疯了,或者你不明白他们对你说了什么。让指针指向文字是绝对没有问题的。
&testpointer
是指向变量testpointer
的指针。这是变量本身的存储位置。
如果你想打印testpointer
指向的位置,你打印它的值(作为void*
,否则operator<<
会将其打印为字符串):
std::cout << "testpointer = " << static_cast<void*>(testpointer) << '
';
另请注意,在现代计算机上,实际上没有ROM。可执行映像从磁盘加载到虚拟内存(“RAM”)中,包括常量字符串文字(实际上是常量字符数组)等数据。
此外,您可以指向常量字符串文字,但它们应该是指向const char
的指针,因为常量字符串文字是常量。问题在于重新分配变量。你会遇到同样的问题,例如
unsigned maxlen = 20;
char* testpointer = new char[sizeof(char) * maxlen];
// ... stuff happens...
testpointer = new char[some_other_size];
如果在第二个delete[]
之前没有new[]
,那么你有内存泄漏。
最后关于你使用std::strncpy
的警告:它不会在最后添加终止' '
。那是因为你提供的大小(第三个参数)小于或等于源字符串的长度,在这种情况下函数不会添加终结符。因此,不要尝试打印“字符串”的内容或将其用作“字符串”。
你的问题有两个误解。
一,你打印的是testpointer
的地址而不是它的值,所以它显然没有改变。如果用&testpointer
替换static_cast<void*>(testpointer)
,你会看到差异。请注意,强制转换是必要的,因为<<
重载char*
以打印字符而不是指针本身。
二,
不要让指针指向文字,因为它会导致内存泄漏
根本不是真的。当且仅当您有一些动态分配的内存并且丢失对该内存的任何引用时,才会发生泄漏;换句话说,如果你不再有指向那个记忆的指针。在这种情况下,您不再有办法解除分配内存,因此泄漏它。
这通过执行以下操作序列在您的程序中发生:
char* testpointer = new char[sizeof(char) * maxlen];
testpointer = "Merry Christmas";
它们中的任何一个都是好的(1),但是它们一起导致泄漏:
- 首先,你分配内存
- 然后,你忘记了它的地址(通过将指针指向别处)。
请注意,涉及的文字是无关紧要的。这将是完全相同的泄漏:
char* testpointer = new char[sizeof(char) * maxlen];
testpointer = nullptr;
就像这样:
char* testpointer = new char[sizeof(char) * maxlen];
testpointer = new char[sizeof(char) * maxlen];
(1)除非你将char *
指向字符串文字,这是自C ++ 11以来不允许的,因为字符串文字是const
。你需要一个const char *
。
我已经学会了不要让指针指向文字,因为它会导致内存泄漏。
指向字符串文字不会导致内存泄漏。可以指向字符串文字。
顺便说一句,你的程序确实泄漏了内存。
但是当我指定一个文字的指针
初始化后,程序不会指定指针。
它仍然指向与以前相同的地址:
您不会流式传输指针指向的地址。您在指针变量上使用addressof运算符,因此您可以流式传输指针所在的地址。即使您指定了指针,这也不会改变。
当我让指针指向文字时,地址不应该改变吗?
指针变量的地址不会改变。但它指向的地址(即指针的值)会改变。但是你既没有指向字符串文字,也没有观察到指向的地址。
以上是关于内存泄漏,指向文字的指针的主要内容,如果未能解决你的问题,请参考以下文章