好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > 解決golang中container/list包中的坑

解決golang中container/list包中的坑

熱門標簽:湛江crm外呼系統排名 上海極信防封電銷卡價格 仙桃400電話辦理 不封卡外呼系統 寧波語音外呼系統公司 宿遷便宜外呼系統代理商 重慶慶云企業400電話到哪申請 地圖標注免費定制店 鄭州智能語音電銷機器人價格

golang中list包用法可以參看這篇文章

但是list包中大部分對于e *Element進行操作的元素都可能會導致程序崩潰,其根本原因是e是一個Element類型的指針,當然其也可能為nil,但是golang中list包中函數沒有對其進行是否為nil的檢查,變默認其非nil進行操作,所以這種情況下,便可能出現程序崩潰。

1.舉個簡單例子

Remove()函數

package main 
import (
 "container/list"
 "fmt"
)
 
func main() {
 l := list.New()
 l.PushBack(1)
 fmt.Println(l.Front().Value) //1
 value := l.Remove(l.Front())
 fmt.Println(value)            //1
 value1 := l.Remove(l.Front()) //panic: runtime error: invalid memory address or nil pointer dereference
 fmt.Println(value1)
}

從程序中可以直觀的看出程序崩潰,原因是list中只有1個元素,但是要刪除2個元素。但是再進一步查看一下原因,便會得出如下結果。

golang中Front()函數實現如下

func (l *List) Front() *Element {
    if l.len == 0 {
        return nil
    }
    return l.root.next
}

由此可見,當第一次刪除之后。list的長度變為0,此時在調用l.Remove(l.Front()),其中l.Front()返回的是一個nil。

接下來再看golang中Remove()函數實現,該函數并沒有判定e是否為nil,變直接默認其為非nil,直接對其進行e.list或者e.Value取值操作。

當e為nil時,這兩個操作都將會造成程序崩潰,這也就是為什么上面程序會崩潰的原因。

func (l *List) Remove(e *Element) interface{} {
 if e.list == l {
  // if e.list == l, l must have been initialized when e was inserted
  // in l or l == nil (e is a zero Element) and l.remove will crash
  l.remove(e)
 }
 return e.Value
}

2.(l *list)PushBackList(other *list)

該函數用于將other list中元素添加在l list的后面。

基本實現思想是取出other中所有元素,將其順次掛載在l列表中,但是golang中實現有問題

代碼如下

func (l *List) PushBackList(other *List) {
 l.lazyInit()
 for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {
  l.insertValue(e.Value, l.root.prev)
 }
}

其具體思想是首先獲取other的長度n,然后循環n次取出其元素將其插入l中。問題就出現在循環n次,如果在這個過程中other的元素變化的話,例如其中有些元素被刪除了,這就導致e的指針可能為nil,此時再利用e.Value取值,程序便會崩潰。

如下所示

package main
 
import (
 "container/list"
 "runtime"
)
 
func main() {
 runtime.GOMAXPROCS(8)
 l := list.New()
 ls := list.New()
 for i := 0; i  10000; i++ {
  ls.PushBack(i)
 }
 go ls.Remove(l.Back())
 l.PushBackList(ls) //invalid memory address or nil pointer dereference
}

如程序中所示,再講ls中元素添加到l過程中,如果ls中元素減少,程序便會崩潰。原因如上面分析。

建議:

在golang中如果對與list的操作只有串行操作,則只需要注意檢查元素指針是否為nil便可避免程序崩潰,如果程序中會并發處理list中元素,建議對list進行加寫鎖(全局鎖),然后再操作。注意,讀寫鎖無法保證并行處理list時程序的安全性。

補充:golang list 鏈表

看代碼吧~

package main 
import (
	"container/list"
	"fmt"
)
 
func main() {
	dataList := list.New()
 
	dataList.PushBack(1)	// 插入末尾
	dataList.PushBack(2)
	dataList.PushFront(3)	 // 插入表頭
	dataList.PushBack(4)
	dataList.PushBack(5)
	m := dataList.PushBack(6)
	m1 := dataList.InsertBefore(7,m)	// 6 之前插入 7
	m2 := dataList.InsertAfter(8,m)	// 6 之后插入 8
 
	// 從鏈表頭開始遍歷
	for e := dataList.Front(); e != nil; e = e.Next() {
		fmt.Println(e.Value) // 打印值
	}
 
	fmt.Println("----------------------------------------")
 
	dataList.Remove(dataList.Front())	// 移除頭部
	dataList.MoveBefore(m2, m)	// 將m2移動m之前
	dataList.MoveAfter(m1, m)
	dataList.Remove(m)	// 移除
 
	//PushBackList	// 插入列表
	//PushFrontList	//
 
	// 從鏈表頭開始遍歷
	for e := dataList.Front(); e != nil; e = e.Next() {
		fmt.Println(e.Value) // 打印值
	}
 
	fmt.Println("----------------------------------------")
 
 
	// 從鏈表尾開始遍歷
	for e := dataList.Back(); e != nil; e = e.Prev() {
		fmt.Println(e.Value, " ")
	}
 
	fmt.Println("----------------------------------------")
	dataList.Init()	// 清空鏈表
	// 從鏈表頭開始遍歷
	for e := dataList.Front(); e != nil; e = e.Next() {
		fmt.Println(e.Value) // 打印值
	}
}

運行結果:

3
1
2
4
5
7
6
8
----------------------------------------
1
2
4
5
8
7
----------------------------------------
7  
8  
5  
4  
2  
1  
----------------------------------------

Process finished with exit code 0

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • linux內核編程container of()函數介紹
  • Flutter通過Container實現時間軸效果
  • 使用 Azure Container Registry 儲存鏡像的問題
  • 基于golang中container/list包的用法說明
  • Docker 退出container后保持繼續運行的操作
  • docker 移除掉運行不正常的container操作
  • 再見 Docker如何5分鐘轉型 containerd
  • C語言container of()函數案例詳解

標簽:吐魯番 雞西 銅川 汕頭 欽州 梅河口 蘭州 重慶

巨人網絡通訊聲明:本文標題《解決golang中container/list包中的坑》,本文關鍵詞  解決,golang,中,container,list,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《解決golang中container/list包中的坑》相關的同類信息!
  • 本頁收集關于解決golang中container/list包中的坑的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 538国产在线| 插插插啊啊啊| 美女的隐私免费视频视频| 蒂法浓厚3D榨取在线最终幻想| 精品人妻无码一二三区视频玉梅美| 床戏超多超欲的电影| 涩色影院| 又大又色又爽AAAA片| 翁公在厨房里轻点好大高雯馨| 777国产精品永久免费观看| 男女一起相嗟嗟嗟免费观看语文版 | 一区二区三区在线精品| 狠狠 鲁 色 人阁丁香| 成?人午夜免费A片无打码| aa2424在线视频看片| 日韩一级黄色大片| 午夜福利伦妓片A片AAA小说 | 青娱乐欧美视频| 羽月希在线授乳月希喂奶| 国产AV精品亚洲八AV电影网站 | 瑞克和莫蒂第五季在线观看| 男男互插| 91视频免费播放| 西川ゆい 在线播放川西结衣 | 改造 调教 药物 催眠h| 无遮挡床戏激烈视频| 波多野结衣亚洲一区二区| 19?韩国主播在线观看柳智慧| 欧美久久久久久精品汤臣一品| 三个护士帮我打了飞机| jlzz大全A片| 日本一区深夜影院深a| 九七电影97电影理论片韩国| 久久久亚洲天堂| 在线看国产| 福利午夜电影| 接待一个25厘米长的客人| 日本熟人妻人伦A片悠田优| 欧美二级片| 国产一区二区三区免费播放| 亚洲第五色综合网|