我已经学会了不要让指针指向文字,因为它会导致内存泄漏。但是当我指定一个文字的指针时,它仍然指向与之前相同的地址:
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中,它应该有不同的地址。我错了吗?
谢谢你,菲利普
答案 0 :(得分:4)
您的cout
说明正在打印名为testpointer
的变量的地址。这是当前函数的堆栈帧中的某个位置。它与testpointer
的值无关,也与testpointer
指向的值无关。
另外,无论是谁告诉你不要让指针指向文字都是疯了,或者你不明白他们对你说了什么。让指针指向文字是绝对没问题的。
答案 1 :(得分:4)
&testpointer
是指向变量testpointer
的指针。它是存储变量本身的地方。
如果要打印testpointer
指向的位置,请打印其值(作为void*
,否则operator<<
会将其打印为字符串) :
std::cout << "testpointer = " << static_cast<void*>(testpointer) << '\n';
另请注意,在现代计算机上,确实没有ROM。可执行映像从磁盘加载到虚拟内存中(&#34; RAM&#34;),其中包括常量字符串文字(实际上是常量字符数组)等数据。
此外,您可以指向常量字符串文字,但它们应该是const char
的指针,因为常量字符串文字是常量。问题出在变量的重新分配上。你会遇到同样的问题,例如
unsigned maxlen = 20;
char* testpointer = new char[sizeof(char) * maxlen];
// ... stuff happens...
testpointer = new char[some_other_size];
如果在第二个delete[]
之前没有new[]
,那么您就会发生内存泄漏。
最后有关您使用std::strncpy
的警告:不会在结尾处添加终止'\0'
。这是因为你提供的大小(第三个参数)小于或等于源字符串的长度,在这种情况下,函数不会添加终止符。因此,请勿尝试打印&#34;字符串&#34;的内容。或者将其用作&#34;字符串&#34;。
答案 2 :(得分:1)
你的问题有两个误解。
一个,您正在打印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 *
。
答案 3 :(得分:0)
我已经学会了不要让指针指向文字,因为它会导致内存泄漏。
指向字符串文字不会导致内存泄漏。可以指向字符串文字。
顺便提一下,你的程序确实泄漏了内存。
但是当我指定一个文字
的指针时
初始化后,程序不会指定指针。
它仍指向与之前相同的地址:
您不会流式传输指针指向的地址。您在指针变量上使用addressof运算符,因此您可以流式传输指针所在的地址。即使您指定了指针,这也不会改变。
当我让指针指向文字时,地址是否应该改变?
指针变量的地址不会改变。但它指向的地址(即指针的值)会改变。但是你既没有指向字符串文字,也没有观察到指向的地址。