繁体   English   中英

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

[英]memory leak, pointer to literal

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

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

谢谢菲利普

您的cout指令正在打印名为testpointer的变量的地址。 那就是当前函数的堆栈框架中的某个位置。 它无关的价值testpointer ,也不与指向的值testpointer

而且,无论是谁告诉您不要让指针指向文字的内容都是疯子,或者您不理解他们对您说的话。 让指针指向文字绝对没有问题。

&testpointer是指向变量testpointer的指针。 它是变量本身的存储位置。

如果要在testpointer指针指向的位置打印,请打印其 (作为void*因为否则operator<<会将其打印为字符串):

std::cout << "testpointer = " << static_cast<void*>(testpointer) << '\n';

另请注意,在现代计算机上,实际上没有ROM。 可执行映像从磁盘加载到虚拟内存(“ RAM”)中,其中包含诸如常量字符串文字(实际上是常量字符数组)之类的数据。

同样,您可以具有指向常量字符串文字的指针,但是它们实际上应该是指向const char指针,因为常量字符串文字是常量。 问题在于变量的重新分配 您可能会遇到例如相同的问题

unsigned maxlen = 20;
char* testpointer = new char[sizeof(char) * maxlen];
// ... stuff happens...
testpointer = new char[some_other_size];

如果第二个new[] delete[]之前没有delete[] ,则可能发生内存泄漏。

最后,关于您使用std::strncpy的警告:它不会在末尾添加终止符'\\0' 这是因为您提供的大小(第三个参数)小于或等于源字符串的长度,在这种情况下,该函数将不添加终止符。 因此,请勿尝试打印“字符串”的内容或将其用作“字符串”。

您的问题有两个误解。

一种是 ,您要打印testpointer地址而不是其 ,因此显然它没有改变。 如果将&testpointer替换为static_cast<void*>(testpointer) ,则会看到不同之处。 请注意,强制转换是必需的,因为char*重载<<以显示字符而不是指针本身。

不要让指针指向文字,因为它会导致内存泄漏

根本不是真的。 当且仅当您拥有一些动态分配的内存并且丢失对该内存的任何引用时,才会发生泄漏。 换句话说,如果您不再有指向该内存的指针。 在这种情况下,您将无法再分配该内存,因此您将泄漏它。

这是通过执行以下操作序列在您的程序中发生的:

char* testpointer = new char[sizeof(char) * maxlen];
testpointer = "Merry Christmas";

它们之一都可以单独运行(1) ,但是它们一起导致泄漏:

  1. 首先,您分配内存
  2. 然后,您忘记了它的地址(通过将指针指向其他位置)。

请注意,涉及的文字是无关紧要的。 这将是完全相同的泄漏:

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


当我让指针指向文字时,地址不应该更改吗?

指针变量的地址不会改变。 但是它指向的地址(即指针的值)将发生变化。 但是,您既不会指向字符串文字,也不会观察所指向的地址。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM