国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

為什么遞歸會造成棧溢出?探索程序的內(nèi)存管理!

存儲
在任何編程語言中,掌握內(nèi)存管理都是很重要的,一方面對于操作系統(tǒng)而言程序內(nèi)存使用是有限制的,另外一方面內(nèi)存變化也會影響我們的程序執(zhí)行效率。

[[403131]]

本文轉(zhuǎn)載自微信公眾號「五月君」,作者五月君。轉(zhuǎn)載本文請聯(lián)系五月君公眾號。

在任何編程語言中,掌握內(nèi)存管理都是很重要的,一方面對于操作系統(tǒng)而言程序內(nèi)存使用是有限制的,另外一方面內(nèi)存變化也會影響我們的程序執(zhí)行效率。

選擇基于 C 語言來學(xué)習(xí),也是因為我們可以借助一些工具。例如,使用 gdb 方便的調(diào)試我們的程序,從每一步的調(diào)試,來看程序的運行變化。

本節(jié)你能學(xué)到什么?

在本文開始前,先列出幾個問題,讀者朋友可以先思考下,也是本講你能學(xué)到的一些知識點,如下:

  • 我們的 32 位操作系統(tǒng)能夠管理的內(nèi)存是多大?對應(yīng) 64 位又是如何?
  • 內(nèi)存空間一般劃分為哪幾個段,每個段存儲都存儲哪些東西?
  • 為什么說棧是一塊連續(xù)的內(nèi)存空間?
  • 為什么遞歸會造成棧溢出?
  • 堆內(nèi)存怎么申請?

前置知識

簡單列舉一些基礎(chǔ)知識點,這些是接下來會用到的。

  • 計算機最小單位是字節(jié)(byte),1byte=8bit(翻譯為中文就是一個字節(jié)等于 8 個二進制位)
  • 計算機底層使用的二進制,如果是用來展示通常是 10 進制,編程用的時候會采用 16 進制,內(nèi)存地址編碼使用的就是 16 進制。
  • 1 個 16 進制數(shù)字就表示 4 位二進制數(shù)字。
  • 32 bit 操作系統(tǒng) 1 個指針占用 4 個字節(jié),64 bit 操作系統(tǒng) 1 個指針占用是 8 個字節(jié)(C 語言中指針變量內(nèi)存地址占有就是 8 字節(jié))。

問題解答:我們的 32 位操作系統(tǒng)能夠管理的內(nèi)存是多大?對應(yīng) 64 位又是如何?

32 位操作系統(tǒng)的地址總線是 32 位,也就是尋址空間是 32 位,因為內(nèi)存是按照字節(jié)尋址的,每個字節(jié)可以理解成對應(yīng)一個地址編號,如下所示,可以是全 0 的,也可以是全 1 的。

  1. 00000000 00000000 00000000 00000000 
  2. ........ ........ ........ ........ 
  3. 11111111 11111111 11111111 11111111 

32 位操作系統(tǒng)能分配的地址編號數(shù)是 

[[403133]]

個字節(jié),排列組合根據(jù)公式換算下:

最終,我們 32 位操作系統(tǒng)最多可管理的內(nèi)存是 4 GB。

注:1024Byte = 1KB | 1024KB = 1MB | 1024MB = 1GB。

內(nèi)存的訪問是比磁盤驅(qū)動器快的多了,因此 4GB 肯定也不滿足不了需求了,隨之而來的是現(xiàn)在的 64 位操作系統(tǒng),理論上它所能管理的內(nèi)存空間為 2 的 64 次方,這個數(shù)字是很大的,這個內(nèi)存現(xiàn)在是足夠用的,通常我們是用不到這么大的。

內(nèi)存劃分

內(nèi)存是交由操作系統(tǒng)管理,它會給我們的內(nèi)存做編號、用戶內(nèi)存與操作系統(tǒng)內(nèi)存隔離。

在 64 位的操作系統(tǒng)上,我們能夠使用的是前面的 48 位,0x0000000000000000 ~ 0x00007FFFFFFFFFFF,而內(nèi)核態(tài)在用戶態(tài)最后一位上加 1 就是 0xFFFF800000000000 ~ 0xFFFFFFFFFFFFFFFF。

問題解答:內(nèi)存空間一般劃分為哪幾個段,每個段存儲都存儲哪些東西?

通過上圖可以清楚的看到,我們的內(nèi)存是有劃分的,一份為系統(tǒng)的內(nèi)核空間,另外一部分為用戶空間,與我們程序相關(guān)的主要看下用戶空間部分,將內(nèi)存劃分為:棧、堆、數(shù)據(jù)段、代碼段,每個里面分別存儲的是什么?下面會分別介紹,答案就在里面。

代碼段

代碼段保存我們代碼編譯后的機器碼,代碼段的內(nèi)存地址也是最小的,下例,以 0x4 開頭,你可以先記住這個值,在后面介紹的其它段里,可以比較下內(nèi)存大小。

  1. (gdb) p &swap 
  2. $11 = (void (*)(int *, int *)) 0x40052d <swap> 
  3. (gdb) p &main 
  4. $12 = (int (*)()) 0x400559 <main> 

 

 

 

數(shù)據(jù)段

數(shù)據(jù)段保存靜態(tài)變量、常量和一些全局變量,以下是一段示例,兩個函數(shù)分別定義了靜態(tài)變量 count 和執(zhí)行了全局變量 globalCount。

  1. #include <stdio.h> 
  2. int globalCount = 0; 
  3. int add(int x, int y) { 
  4.   static int count = 0; 
  5.   count++; 
  6.   globalCount++; 
  7.   return x + y; 
  8. int sub(int x, int y) { 
  9.   static int count = 0;  
  10.   count++; 
  11.   globalCount++; 
  12.   return x + y; 
  13.  
  14. int main() { 
  15.   int a = 6; 
  16.   int b = 3; 
  17.   int s1 = add(a, b); 
  18.   int s2 = sub(a, b); 
  19.   printf("s1=%d s2=%d", s1, s2); 

通過 gdb 調(diào)試看下,分別在 add 函數(shù)里打印了靜態(tài)變量 count 和全局變量 globalCount 的內(nèi)存地址。

靜態(tài)變量 count 是聲明在函數(shù)內(nèi)部的,因此兩次打印出來的地址也是不一樣的,自然兩個是不會相互影響的,全局變量可以看到內(nèi)存地址是一樣的,因此在任意一個函數(shù)里修改,值都會發(fā)生變化。

0x601038、0x60103c、0x601040 每次遞增 4 個字節(jié),可以看到它們的內(nèi)存地址是連續(xù)遞增的,數(shù)據(jù)段的內(nèi)存地址以 0x6 開頭是大于代碼段的。

  1. add (x=6, y=3) at main2.c:5 
  2. 5   count++; 
  3. (gdb) p &count 
  4. $1 = (int *) 0x60103c <count.2181> 
  5. (gdb) p &globalCount 
  6. $2 = (int *) 0x601038 <globalCount> 
  7.  
  8. sub (x=6, y=3) at main2.c:11 
  9. 11   count++; 
  10. (gdb) p &count 
  11. $3 = (int *) 0x601040 <count.2186> 
  12. (gdb) p &globalCount 
  13. $4 = (int *) 0x601038 <globalCount> 

數(shù)據(jù)段還有一種稱為 “BSS” 段,表示未初始化或初始化為 0 的所有全局變量或靜態(tài)變量,static int a 或全局變量 int a 稱為 “未初始化數(shù)據(jù)段”。

關(guān)于初始化數(shù)據(jù)段與未初始化數(shù)據(jù)段,這里有篇文章講的也很好,可以參考 https://zhuanlan.zhihu.com/p/62208277。

棧段

棧寄存器段,指向包含當(dāng)前程序棧的段,這些都是臨時的信息。例如:局部變量、函數(shù)參數(shù)、返回值和當(dāng)前程序運行狀態(tài)等都存在于棧中,隨著這些臨時變量對應(yīng)的作用域完成之后,也會被彈出棧。

一個變量交換示例

以下為一段 C 語言代碼示例,通過 swap 函數(shù)交換兩個變量。

  1. // main.c 
  2. #include <stdio.h> 
  3. void swap(int *a, int *b) { 
  4.   int temp = *a; 
  5.   *a = *b; 
  6.   *b = temp
  7. int main() { 
  8.   int a = 2; 
  9.   int b = 3; 
  10.   swap(&a, &b); 
  11.   printf("a=%d b=%d", a, b); 

先使用 gcc 編譯我們的源代碼 gcc -g main.c -o main.out,之后使用 gdb 調(diào)試。

問題解答:為什么說棧是一塊連續(xù)的內(nèi)存空間?

在 C 語言里一個整型的數(shù)據(jù)大小為 4 個字節(jié)(指針類型另有規(guī)定,后面會講),整型變量 a 存儲的內(nèi)存地址為 0x7fffffffe35c 也即首地址,按照 4 Byte 推算應(yīng)該是 0x7fffffffe35c、0x7fffffffe35d、0x7fffffffe35e、0x7fffffffe35f。整型變量 b 的內(nèi)存地址為 0x7fffffffe358 同樣按照 4 Byte 推算應(yīng)該是 0x7fffffffe358、0x7fffffffe359、0x7fffffffe35a、0x7fffffffe35b 也就是加上 4 個字節(jié)正好相鄰于變量 a,因此我們還可以在確認(rèn)一個問題是:“棧是一塊連續(xù)的內(nèi)存區(qū)域”。

通過一個圖,相對直觀的感受下。

這時可能會產(chǎn)生一個疑問,為什么創(chuàng)建變量順序是 a、b 而分配的內(nèi)存地址確是遞減的順序?

這涉及到棧的存儲結(jié)構(gòu),棧是先進后出的,棧頂?shù)牡刂肥怯上到y(tǒng)預(yù)先設(shè)置好的,由棧頂入棧隨后每次內(nèi)存地址呈遞減的方式依次分配,當(dāng)還有新元素時就繼續(xù)壓棧,最先入棧的最后出棧,也可理解為棧底對應(yīng)高地址、棧頂對應(yīng)低地址。

  1. (gdb) p &a 
  2. $1 = (int *) 0x7fffffffe35c 
  3. (gdb) p &b 
  4. $2 = (int *) 0x7fffffffe358 

使用 gdb 調(diào)試進入 swap 函數(shù),這兩個參數(shù) a、b 我們定義為指針類型,可以看到它的值為外層整型變量 a 和 b 的內(nèi)存地址。

swap 函數(shù)里的指針類型變量 a 與 b 也是有內(nèi)存地址的,可以打印出來看下。同樣的可以看出,這兩個內(nèi)存地址之間相差 8 個字節(jié),也就號符合指針類型的定義,在 64 位系統(tǒng)下一個指針占用 8 個字節(jié),當(dāng)然大學(xué)課本上你可能看到過 1 個指針占用 4 個字節(jié),那是針對的 32 位系統(tǒng)。

  1. swap (a=0x7fffffffe35c, b=0x7fffffffe358) at main.c:3 
  2. 3   int temp = *a; 
  3. (gdb) p &a 
  4. $1 = (int **) 0x7fffffffe328 
  5. (gdb) p &b 
  6. $2 = (int **) 0x7fffffffe320 

目前處于代碼的第 3 行,swap 函數(shù)里指針變量 a 存儲的是外層傳入的變量 a 的內(nèi)存地址,如何獲取該值呢?那么在 C 語言中通過運算符 * 號可以取到一個內(nèi)存地址對應(yīng)的值,也就是“解引用”。

  1. (gdb) p *a 
  2. $3 = 2 

接下來執(zhí)行 2 兩步,程序停留在第 5 行,可以看到 a 的值由 2 變?yōu)榱?3,為什么 swap 函數(shù)能交換兩個變量的值,也正是因為我們在這里通過指針修改了傳進來的兩個變量的內(nèi)存地址。

  1. (gdb) n 
  2. 4   *a = *b; 
  3. (gdb) n 
  4. 5   *b = temp
  5. (gdb) p *a 
  6. $4 = 3 

查看函數(shù)堆棧

通過 bt 可以打印當(dāng)前函數(shù)調(diào)用棧的所有信息,左側(cè)有一個 #0、#1 的序號,0 就是目前的棧頂,因為我們這個程序很簡單,程序入口函數(shù) main() 就是我們的棧底,而當(dāng)前執(zhí)行的 swap() 函數(shù)就是我們的棧頂,也是當(dāng)前程序所在的位置。

  1. (gdb) bt 
  2. #0  swap (a=0x7fffffffe35c, b=0x7fffffffe358) at main.c:5 
  3. #1  0x0000000000400582 in main () at main.c:11 

棧溢出

棧是有內(nèi)存大小限制的,Linux 或 Mac 下我們可通過 ulimit -s 命令查看,結(jié)果為:8192 # stack size (kbytes) ,Linux 下用戶默認(rèn)的棧空間大小為 8MB。

遞歸造成的棧溢出

寫遞歸時,通常要控制好邊界,避免出現(xiàn)無限遞歸,遞歸的層級也不要太深,盡量不要在棧上定義太大的數(shù)據(jù)。一段遞歸調(diào)用的程序如下所示:

  1. #include <stdio.h> 
  2.  
  3. void call() 
  4.   int a[2048]; 
  5.   printf("hello call! \n"); 
  6.   call(); 
  7. int main(int argc, char *argv[]) { 
  8.   call(); 

gdb 調(diào)試之后得到如下錯誤信息:

  1. Program received signal SIGSEGV, Segmentation fault. 
  2. 0x000000000040053d in call () at a.c:6 

bt -n 從棧底打印 n 條信息,最下面為我們的 main 函數(shù),除此之外可以看到 call() 總共遞歸調(diào)用了 1022 次,因為最上面序號是從 0 開始的。

  1. (gdb) bt -5 
  2. #1018 0x000000000040054c in call () at a.c:7 
  3. #1019 0x000000000040054c in call () at a.c:7 
  4. #1020 0x000000000040054c in call () at a.c:7 
  5. #1021 0x000000000040054c in call () at a.c:7 
  6. #1022 0x0000000000400567 in main (argc=1, argv=0x7fffffffe458) at a.c:10 

問題解答:為什么遞歸會造成棧溢出?

當(dāng)我們遞歸一個函數(shù)時,這個時候每一次的遞歸運行都會做壓棧操作,棧是一種先進后出的數(shù)據(jù)結(jié)構(gòu),系統(tǒng)也是有最大的空間限制的,Linux 下用戶默認(rèn)的棧空間大小為 8MB,當(dāng)棧的存放容量超出這個限制之后,通常我們的程序會得到棧溢出得到錯誤。

留一個問題大家思考下??:通過上面我們知道了遞歸層級太深會導(dǎo)致棧溢出,這是因為系統(tǒng)會有棧空間大小限制的,筆者平常使用 JavaScript 相會多一些,如果是在 JavaScript 中遇到這種問題怎么解決?不知道也沒關(guān)系,筆者最近在寫一個系列文章 《JavaScript 異步編程指南》可以帶你一起深入了解這個問題。

字符數(shù)組造成的棧溢出

模擬這個問題很簡單,創(chuàng)建一個過大的字符數(shù)組。

  1. #include<stdio.h> 
  2. int main() 
  3.  char str[8192 * 1024]; 
  4.  int size = sizeof(str); 
  5.  
  6.  printf("size: %d\n"size); 

通過 gdb 調(diào)試,會得到一個 “Segmentation fault” 通常也稱為段錯誤,指的是訪問的內(nèi)存超出了系統(tǒng)給程序設(shè)定的內(nèi)存空間,一般包括:不存在的內(nèi)存地址、訪問了系統(tǒng)保護的內(nèi)存地址、訪問了只讀的內(nèi)存地址、棧溢出等。

  1. Program received signal SIGSEGV, Segmentation fault. 
  2. 0x000000000040054e in main () at index.c:7 

解決這種問題,繼續(xù)往下看~

堆段

堆段由開發(fā)者手動申請分配和釋放,也稱動態(tài)內(nèi)存分配。在 C 語言中可以使用系統(tǒng)提供的函數(shù) malloc() 和 free() 申請和釋放內(nèi)存。

繼續(xù)拿上面 “字符數(shù)組棧溢出” 這個示例,現(xiàn)在改成在堆中創(chuàng)建內(nèi)存,這時僅在棧中保存指針變量 str 的地址,真正數(shù)據(jù)存放于堆中,也就不會出現(xiàn)棧溢出問題了。

  1. #include <stdio.h> 
  2. #include <malloc.h> 
  3. int main() 
  4.  char *str = (char *)malloc(8192 * 1024); 
  5.  if (str == NULL) { 
  6.    printf("Heap memory application failed."); 
  7.    return 0; 
  8.  } 
  9.  printf("Heap memory application successed."); 
  10.  
  11.  free(str); 
  12.  str = NULL
  13.  return 0; 

進入 gdb 調(diào)試,代碼停留在第 5 行,在未分配堆內(nèi)存之前,打印 str 可以看到是沒有值的,而 &str 取的是該變量在棧空間的內(nèi)存地址 0x7fffffffe368,這不是一回事,這是該變量的值。

再次執(zhí)行,創(chuàng)建堆內(nèi)存,代碼停留在第 12 行 free(str) 打印 str 得到 0x7ffff720c010 這時候堆內(nèi)存已分配成功。

現(xiàn)在讓我們做釋放操作,代碼停留在 14 行,打印 str 可以看到值已被釋放。

  1. # 未分配 
  2. Temporary breakpoint 1, main () at b.c:5 
  3. 5  char *str = (char *)malloc(8192 * 1024); 
  4. (gdb) p str 
  5. $1 = 0x0 
  6. (gdb) p &str 
  7. $2 = (char **) 0x7fffffffe368 
  8. (gdb) n 
  9.  
  10. # 已分配 
  11. 6  if (str == NULL) { 
  12. (gdb) n 
  13. 10  printf("Heap memory application successed."); 
  14. (gdb) n 
  15.  
  16. # 釋放 
  17. 12  free(str); 
  18. (gdb) p str 
  19. $3 = 0x7ffff720c010 "" 
  20. (gdb) n 
  21. 13  str = NULL
  22. (gdb) n 
  23. 14  return 0; 
  24. (gdb) p str 
  25. $4 = 0x0 
  26. (gdb) p &str 
  27. $5 = (char **) 0x7fffffffe368 

總結(jié)

本文也是筆者在之前學(xué)習(xí)過程中的總結(jié),近期又稍微整理下,發(fā)出來也是希望能與大家共同的分享、交流。

通過本文,幾個常見的知識點:棧與堆的區(qū)別、為什么遞歸會造成棧溢出,類似于這種常見的問題,希望讀者朋友能夠掌握。

 

 

責(zé)任編輯:武曉燕 來源: 五月君
相關(guān)推薦

2024-12-16 09:11:57

2020-10-27 08:58:47

設(shè)計NUMA內(nèi)存

2022-05-09 14:09:23

多線程線程安全

2016-10-31 20:56:57

Javascript閉包內(nèi)存泄漏

2024-09-09 09:41:03

內(nèi)存溢出golang開發(fā)者

2025-04-01 05:22:00

JavaThread變量

2022-10-18 08:38:16

內(nèi)存泄漏線程

2018-04-24 14:58:06

內(nèi)存降價漲價

2021-09-17 11:08:05

內(nèi)存

2013-06-19 10:55:40

Disruptor并發(fā)框架

2013-09-26 09:34:56

女程序員

2021-11-01 22:36:04

JavaScript

2023-05-31 09:00:00

2020-06-10 14:10:53

服務(wù)開發(fā) 架構(gòu)

2025-01-10 09:51:10

內(nèi)存Java應(yīng)用程序

2015-12-04 15:21:43

2021-08-26 05:00:44

生產(chǎn)環(huán)境內(nèi)存

2021-03-24 10:00:32

Python遞歸函數(shù)Python基礎(chǔ)

2015-03-30 11:18:50

內(nèi)存管理Android

2012-05-15 02:04:22

JVMJava
點贊
收藏

51CTO技術(shù)棧公眾號

久久天天狠狠| 日韩黄色av| 一个人www视频在线免费观看| 另类人妖一区二区av| 久久精品视频在线观看| 欧美极品免费| 日本高清+成人网在线观看| 亚洲春色h网| 视频一区不卡| 国产精品美女视频| 亚洲精品一线| 国产成人精品在线观看| 色婷婷色综合| 国产一区二区网| 欧美日韩国产精品成人| 国产精品久久久久久久久久辛辛| 91精品视频免费观看| 99精品视频中文字幕| 青青在线视频| 国产日韩精品视频| 26uuu国产电影一区二区| 日本高清在线观看wwwww色| 欧美一区视频在线| 国产精品一区久久久久| 成人午夜影视| 日韩美女在线看| 免费不卡中文字幕在线| 欧美性视频在线播放| 一区2区3区在线看| 网友自拍亚洲| 欧洲另类一二三四区| 在线天堂资源| 国内精品久久国产| 亚洲一二三区视频在线观看| 亚洲aⅴ网站| 久久国产精品网| 精品国一区二区三区| 日韩aaa久久蜜桃av| 国产精品免费区二区三区观看| 日韩av超清在线观看| 欧美最猛性xxxx| 久久精品麻豆| 国产熟女高潮视频| 香蕉av福利精品导航| 亚洲优女在线| 亚洲一区亚洲二区| 久久久噜噜噜久噜久久综合| 九一国产在线| 国产乱码精品一品二品| 中文字幕 91| 欧美日韩免费不卡视频一区二区三区| 成人视屏在线观看| 91日韩久久| 国产日韩欧美不卡在线| heyzo一区| 国产精品极品美女粉嫩高清在线| 成人黄色777网| 国产精品久久久久久久久借妻| 国产精选一区二区三区| 一区二区在线播放视频| 成人av在线播放网址| 成人h动漫在线| 色婷婷综合成人av| 一区二区三区四区在线播放 | 91精品福利视频| 最近中文字幕mv第三季歌词| 蜜臀av性久久久久蜜臀av麻豆| 国产精品国产精品| 欧美一级一区| av不卡在线免费观看| 国产一区二区三区亚洲综合| 黑人欧美xxxx| 日本美女高清在线观看免费| 久久久极品av| 日本一不卡视频| 国产无遮挡又黄又爽免费软件 | 一本久道久久综合| 中文字幕在线不卡视频| 最猛黑人系列在线播放| 91麻豆精品国产无毒不卡在线观看| 欧美高清另类hdvideosexjaⅴ| 日韩亚洲欧美成人一区| 亚洲国产一区二区三区在线播 | 久久久91精品| 久久97精品| 98国产高清一区| 免费视频最近日韩| 僵尸世界大战2 在线播放| 欧美日韩激情视频8区| 婷婷免费在线观看| 国产精品一级片在线观看| 视频一区视频二区视频三区视频四区国产| 国产成人亚洲综合色影视| 视频一区二区三区在线看免费看| 亚洲欧美一区二区精品久久久| 在线视频自拍| 亚洲高清福利视频| 一级毛片在线视频| 久久亚洲综合国产精品99麻豆精品福利 | 在线丨暗呦小u女国产精品| 翔田千里在线视频| 日韩电影中文字幕av| 青青草久久爱| 亚洲成人蜜桃| 91在线视频免费观看| 日本中文字幕一区二区有码在线 | 免费亚洲一区| 国产女女做受ⅹxx高潮| 一本久道久久综合狠狠爱| 国产一区二区黄| 成人羞羞网站| 50度灰在线观看| 日韩精品视频在线免费观看| 日本精品视频| 日韩精品福利网站| 亚洲天堂2018av| 日韩欧美一区二区在线视频| 欧美理论在线播放| 激情亚洲色图| 欧美成人午夜视频| 国产精品一区二区果冻传媒| av免费在线观看网址| 国产精品初高中精品久久| 岛国av在线不卡| 欧美视频免费| 亚洲a∨一区二区三区| 欧美精品视频www在线观看| 亚洲欧美日韩一级| www国产91| 香蕉精品999视频一区二区| 国产不卡视频| 久久精品一区中文字幕| 亚洲毛片一区| 久草电影在线| 免费av一区二区| 日本欧美加勒比视频| 免费一级淫片| 欧美激情亚洲自拍| 美女爽到高潮91| 国产91在线高潮白浆在线观看| 蜜桃一区二区三区在线| 婷婷av在线| 成人在线免费网站| 国产一区白浆| 黄页网站在线观看| 欧美最顶级丰满的aⅴ艳星| 亚洲一区二区四区蜜桃| 无圣光视频在线观看| 欧美人与禽zozo性伦| 国产最新精品| 国产粉嫩一区二区三区在线观看| 国产精品成人一区二区三区| 精品国产sm最大网站免费看| 国产不卡视频一区| 久久男人天堂| 亚洲天堂网站在线观看视频| 成年人国产精品| 欧美丝袜足交| 黄色片视频在线观看| 91入口在线观看| 欧美影院一区二区| 欧美日本一区| 丝袜在线观看| 日韩欧美亚洲在线| 亚洲视频在线免费看| 大黄网站在线观看| 久久99精品久久久久久三级| 在线精品亚洲一区二区不卡| 日韩av在线播放网址| 中文字幕国产免费| 久久久久久91| 亚洲免费观看高清完整版在线观看熊 | 777a∨成人精品桃花网| 奇米精品一区二区三区四区| 3d动漫一区二区三区| 色噜噜国产精品视频一区二区| 国产亚洲一区二区三区四区| 狠狠操综合网| 成人av免费| 国产精品三级一区二区| 国产大片精品免费永久看nba| 色狠狠av一区二区三区| 国产一区福利在线| 6080成人| 欧美日韩国产高清视频| 亚洲精品99久久久久中文字幕| 成人精品免费看| 天堂成人娱乐在线视频免费播放网站| 国产在线观看黄| 中文精品一区二区三区| 欧美大尺度激情区在线播放 | 精品一区二区三区中文字幕在线| 国产精品久久999| 欧美一区二区精品| 久久久国产精品不卡| 国产精品va| www.神马久久| 在线看一级片| jizzjizzjizz亚洲女| 清纯唯美一区二区三区|