我有以下代碼來反轉一個鏈表。為什么我得到了一個運行時錯誤:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==31==ERROR: AddressSanitizer。SEGV on unknown address 0x000000000010 (pc 0x000000370a97 bp 0x7fffed631a10 sp 0x7fffed6318c0 T0)
==31==該信號是由一個READ記憶體訪問引起的。
==31==提示:地址指向零頁。
#4 0x7f165e0300b2(/lib/x86_64-linux-gnu/libc.so.6 0x270b2)
AddressSanitizer可以不提供額外資訊。
==31==ABORTING
如果我把 "cout<<pre<<endl; "這一行注釋掉,會怎么樣呢?
/**.
* 單一鏈接的串列的定義。
* 結構 ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}.
* ListNode(int x) : val(x), next(nullptr) {}.
* ListNode(int x, ListNode *next) : val(x), next(next) {}.
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head) return head;
ListNode* temp = head;
ListNode* pre;
cout<<pre<<endl。
ListNode* cur = head;
while(cur->next){
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
cur->next = pre。
return cur。
}
};
如果我不注釋這一行,cout每次都會列印一個隨機的地址,而程式會成功地逆轉鏈表,沒有任何錯誤。 問題的鏈接:https://leetcode.com/problems/reverse-linked-list/
uj5u.com熱心網友回復:
一個未初始化的變數有一個不確定的值(除了當變數被宣告在靜態記憶體中時,如果你不明確設定一個值,那么它的初始值為0)。 請參閱默認變數值。
。在指標的情況下,試圖解除對未指向有效記憶體的指標的參考是未定義行為。
在你的例子中,你需要將pre初始化為NULL,這樣你的代碼才能正常作業,否則你的串列將最終被破壞,包含無效的指標。
例如,假設你以這個串列開始:
---------- ----------
| val=1 | /-> | val=2 | /-> | val=3 | /->?
|接下來=2 | -/ |接下來=3 | -/ |接下來=0 |
---------- ---------- ----------
^
|
head, cur
在第1次回圈迭代之后,現在的串列看起來是這樣的:
---------- ----------
| val=1 | val=2 | /-> | val=3 | /->.
| next=P | | next=3 | -/ | next=0 |
---------- ---------- ----------
^
|
咖
在下一次迭代之后,現在的串列將看起來像這樣:
---------- ----------
| val=1 | <- | val=2 | | val=3 |
| next=P | - | next=1 | next=0 |
---------- ---------- ----------
^
|
咖
然后回圈結束,cur->next最后一次被更新,所以串列最后看起來像這樣:
---------- ----------
| val=1 | <- | val=2 | <- | val=3 |
|接下來=P | - |接下來=1 | - |接下來=2 |
---------- ---------- ----------
^
|
回傳
注意到問題了嗎?
你已經有效地反轉了串列,但是 "最后一個 "節點上的next=P指向哪里?
如果
pre沒有被初始化,那么next=P將是不確定的(讓我們假設pre沒有隨機初始化為NULL,這將是極其罕見的)。因此,任何之后試圖遍歷串列的代碼將無法確定串列的結束位置,并將試圖訪問一個不存在的節點!如果
pre被正確地初始化為NULL,那么next=P將是NULL,從而正確地終止了串列。
uj5u.com熱心網友回復:
考慮到你的代碼:
ListNode* pre;
cout<<pre<<endl。
ListNode* cur = head;
while(cur->next){
temp = cur->next;
cur->next = pre;
pre顯然是未初始化的,它被用來初始化cur->next,它將是head->next。因此,head->next在例程回傳時將持有一個未初始化的指標值。
如果有代碼在呼叫你的Solution后檢查它,該代碼將需要驗證一個無效的指標值,這將導致未定義行為。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/315455.html
標籤:
上一篇:Elasticsearch。多個關鍵詞不能搜索所有欄位
下一篇:C語言中的函式指標?
