真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語言變量在棧還是堆 go語言struct

局部變量是存放在棧中,還是存放在堆棧中?

你好!

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:域名注冊、網(wǎng)絡空間、營銷軟件、網(wǎng)站建設、安寧網(wǎng)站維護、網(wǎng)站推廣。

程序中的局部變量存放在棧中,因而不能太大,如:

double

a[1000][1000];就可能不能通過編譯。用戶動態(tài)分配的內(nèi)存,分配于堆中,可以很大。如

double

**a

=

new

double

*[1000];

for(int

i

=

0;

i

1000;

++i)

a[i]

=

new

double

[1000];

希望對你有所幫助,望采納。

堆和棧的區(qū)別? 全局變量在哪里存 ,靜態(tài)變量在哪里存?

問題1:

堆Heap指的是用malloc和free,new和delete等函數(shù)動態(tài)創(chuàng)建的內(nèi)存空間,由程序員自己維護和管理;

棧Stack指的是函數(shù)1跳轉(zhuǎn)進入子函數(shù)2之前,為了保護函數(shù)1的現(xiàn)場(CPU寄存器狀態(tài)等信息,委的就是子函數(shù)2執(zhí)行結(jié)束,還能夠返回到函數(shù)1)操作系統(tǒng)自動進行的壓棧和出棧操作;另外,我記得函數(shù)1進入子函數(shù)2之后,子函數(shù)2內(nèi)部的臨時變量也是由操作系統(tǒng)在棧中分配的。

問題2:

全局變量在編譯時就被編譯器固定在“數(shù)據(jù)段”了,占了數(shù)據(jù)段中的位置(存儲空間);

靜態(tài)變量我沒有研究過,不敢輕言。

go程序如何分配堆棧的

在Go語言中有一些調(diào)試技巧能幫助我們快速找到問題,有時候你想盡可能多的記錄異常但仍覺得不夠,搞清楚堆棧的意義有助于定位Bug或者記錄更完整的信息。

本文將討論堆棧跟蹤信息以及如何在堆棧中識別函數(shù)所傳遞的參數(shù)。

Functions

先從這段代碼開始:

Listing 1

01 package main

02

03 func main() {

04 ? ? slice := make([]string, 2, 4)

05 ? ? Example(slice, "hello", 10)

06 }

07

08 func Example(slice []string, str string, i int) {

09 ? ? panic("Want stack trace")

10 }

Example函數(shù)定義了3個參數(shù),1個string類型的slice, 1個string和1個integer, 并且拋出了panic,運行這段代碼可以看到這樣的結(jié)果:

Listing 2

Panic: Want stack trace

goroutine 1 [running]:

main.Example(0x2080c3f50, 0x2, 0x4, 0x425c0, 0x5, 0xa)

/Users/bill/Spaces/Go/Projects/src/github.com/goinaction/code/

temp/main.go:9 +0x64

main.main()

/Users/bill/Spaces/Go/Projects/src/github.com/goinaction/code/

temp/main.go:5 +0x85

goroutine 2 [runnable]:

runtime.forcegchelper()

/Users/bill/go/src/runtime/proc.go:90

runtime.goexit()

/Users/bill/go/src/runtime/asm_amd64.s:2232 +0x1

goroutine 3 [runnable]:

runtime.bgsweep()

/Users/bill/go/src/runtime/mgc0.go:82

runtime.goexit()

/Users/bill/go/src/runtime/asm_amd64.s:2232 +0x1

堆棧信息中顯示了在panic拋出這個時間所有的goroutines狀態(tài),發(fā)生的panic的goroutine會顯示在最上面。

Listing 3

01 goroutine 1 [running]:

02 main.Example(0x2080c3f50, 0x2, 0x4, 0x425c0, 0x5, 0xa)

/Users/bill/Spaces/Go/Projects/src/github.com/goinaction/code/

temp/main.go:9 +0x64

03 main.main()

/Users/bill/Spaces/Go/Projects/src/github.com/goinaction/code/

temp/main.go:5 +0x85

第1行顯示最先發(fā)出panic的是goroutine 1, 第二行顯示panic位于main.Example中, 并能定位到該行代碼,在本例中第9行引發(fā)了panic。

下面我們關(guān)注參數(shù)是如何傳遞的:

Listing 4

// Declaration

main.Example(slice []string, str string, i int)

// Call to Example by main.

slice := make([]string, 2, 4)

Example(slice, "hello", 10)

// Stack trace

main.Example(0x2080c3f50, 0x2, 0x4, 0x425c0, 0x5, 0xa)

這里展示了在main中帶參數(shù)調(diào)用Example函數(shù)時的堆棧信息,比較就能發(fā)現(xiàn)兩者的參數(shù)數(shù)量并不相同,Example定義了3個參數(shù),堆棧中顯示了6個參數(shù)。現(xiàn)在的關(guān)鍵問題是我們要弄清楚它們是如何匹配的。

第1個參數(shù)是string類型的slice,我們知道在Go語言中slice是引用類型,即slice變量結(jié)構(gòu)會包含三個部分:指針、長度(Lengthe)、容量(Capacity)

Listing 5

// Slice parameter value

slice := make([]string, 2, 4)

// Slice header values

Pointer: ?0x2080c3f50

Length: ? 0x2

Capacity: 0x4

// Declaration

main.Example(slice []string, str string, i int)

// Stack trace

main.Example(0x2080c3f50, 0x2, 0x4, 0x425c0, 0x5, 0xa)

因此,前面3個參數(shù)會匹配slice, 如下圖所示:

Figure 1

figure provided by Georgi Knox

我們現(xiàn)在來看第二個參數(shù),它是string類型,string類型也是引用類型,它包括兩部分:指針、長度。

Listing 6

// String parameter value

"hello"

// String header values

Pointer: 0x425c0

Length: ?0x5

// Declaration

main.Example(slice []string,?str string, i int)

// Stack trace

main.Example(0x2080c3f50, 0x2, 0x4,?0x425c0, 0x5, 0xa)

可以確定,堆棧信息中第4、5兩個參數(shù)對應代碼中的string參數(shù),如下圖所示:

Figure 2

figure provided by Georgi Knox

最后一個參數(shù)integer是single word值。

Listing 7

// Integer parameter value

10

// Integer value

Base 16: 0xa

// Declaration

main.Example(slice []string, str string,?i int)

// Stack trace

main.Example(0x2080c3f50, 0x2, 0x4, 0x425c0, 0x5,?0xa)

現(xiàn)在我們可以匹配代碼中的參數(shù)到堆棧信息了。

Figure 3

figure provided by Georgi Knox

Methods

如果我們將Example作為結(jié)構(gòu)體的方法會怎么樣呢?

Listing 8

01 package main

02

03 import "fmt"

04

05 type trace struct{}

06

07 func main() {

08 ? ? slice := make([]string, 2, 4)

09

10 ? ? var t trace

11 ? ? t.Example(slice, "hello", 10)

12 }

13

14 func (t *trace) Example(slice []string, str string, i int) {

15 ? ? fmt.Printf("Receiver Address: %p\n", t)

16 ? ? panic("Want stack trace")

17 }

如上所示修改代碼,將Example定義為trace的方法,并通過trace的實例t來調(diào)用Example。

再次運行程序,會發(fā)現(xiàn)堆棧信息有一點不同:

Listing 9

Receiver Address:?0x1553a8

panic: Want stack trace

01 goroutine 1 [running]:

02 main.(*trace).Example(0x1553a8, 0x2081b7f50, 0x2, 0x4, 0xdc1d0, 0x5, 0xa)

/Users/bill/Spaces/Go/Projects/src/github.com/goinaction/code/

temp/main.go:16 +0x116

03 main.main()

/Users/bill/Spaces/Go/Projects/src/github.com/goinaction/code/

temp/main.go:11 +0xae

首先注意第2行的方法調(diào)用使用了pointer receiver,在package名字和方法名之間多出了"*trace"字樣。另外,參數(shù)列表的第1個參數(shù)標明了結(jié)構(gòu)體(t)地址。我們從堆棧信息中看到了內(nèi)部實現(xiàn)細節(jié)。

Packing

如果有多個參數(shù)可以填充到一個single word, 則這些參數(shù)值會合并打包:

Listing 10

01 package main

02

03 func main() {

04 ? ? Example(true, false, true, 25)

05 }

06?

07 func Example(b1, b2, b3 bool, i uint8) {

08 ? ? panic("Want stack trace")

09 }

這個例子修改Example函數(shù)為4個參數(shù):3個bool型和1個八位無符號整型。bool值也是用8個bit表示,所以在32位和64位架構(gòu)下,4個參數(shù)可以合并為一個single word。

Listing 11

01 goroutine 1 [running]:

02 main.Example(0x19010001)

/Users/bill/Spaces/Go/Projects/src/github.com/goinaction/code/

temp/main.go:8 +0x64

03 main.main()

/Users/bill/Spaces/Go/Projects/src/github.com/goinaction/code/

temp/main.go:4 +0x32

這是本例的堆棧信息,看下圖的具體分析:

Listing 12

// Parameter values

true, false, true, 25

// Word value

Bits ? ?Binary ? ? ?Hex ? Value

00-07 ? 0000 0001 ??01? ??true

08-15 ? 0000 0000 ??00? ? false

16-23 ? 0000 0001 ??01? ? true

24-31 ? 0001 1001 ??19? ? 25

// Declaration

main.Example(b1, b2, b3 bool, i uint8)

// Stack trace

main.Example(0x19010001)

以上展示了參數(shù)值是如何匹配到4個參數(shù)的。當我們看到堆棧信息中包括十六進制值,需要知道這些值是如何傳遞的。


網(wǎng)頁題目:go語言變量在棧還是堆 go語言struct
標題路徑:http://weahome.cn/article/dohcced.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部