簡體   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