内存泄漏,指向文字的指针

时间:2017-12-20 13:02:22

标签: c++ pointers memory-leaks

我已经学会了不要让指针指向文字,因为它会导致内存泄漏。但是当我指定一个文字的指针时,它仍然指向与之前相同的地址:

    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中,它应该有不同的地址。我错了吗?

谢谢你,菲利普

4 个答案:

答案 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),但是它们一起导致泄漏:

  1. 首先,你分配内存
  2. 然后,你忘记了它的地址(把指针指向别处)。
  3. 请注意,涉及的文字无关紧要。这将是完全相同的泄漏:

    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运算符,因此您可以流式传输指针所在的地址。即使您指定了指针,这也不会改变。

  

当我让指针指向文字时,地址是否应该改变?

指针变量的地址不会改变。但它指向的地址(即指针的值)会改变。但是你既没有指向字符串文字,也没有观察到指向的地址。