久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言运行时库详解

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言运行时库详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

網址:http://blog.csdn.net/jxth152913/archive/2010/07/02/5708369.aspx

運行時庫是程序在運行時所需要的庫文件,通常運行時庫是以LIB或DLL形式提供的。C運行時庫誕生于20世紀70年代,當時的程序世界還很單純,應用程序都是單線程的,多任務或多線程機制在此時還屬于新觀念。所以這個時期的C運行時庫都是單線程的。

  隨著操作系統?多線程技術的發展?,最初的C運行時庫無法滿足程序的需求,出現了嚴重的問題?。C運行時庫使用了多個全局變量(例如errno)和靜態變量,這可能在多線程程序中引起沖突。假設兩個線程都同時設置errno,其結果是后設置的errno會將先前的覆蓋,用戶得不到正確的錯誤信息。

  因此,Visual C++提供了兩種版本的C運行時庫。一個版本供單線程應用程序調用,另一個版本供多線程應用程序調用。多線程運行時庫與單線程運行時庫有兩個重大差別:

  (1)類似errno的全局變量,每個線程單獨設置一個;

  這樣從每個線程中可以獲取正確的錯誤信息。

  (2)多線程庫中的數據結構以同步機制加以保護。

  這樣可以避免訪問時候的沖突。

  Visual C++提供的多線程運行時庫又分為靜態鏈接庫和動態鏈接庫兩類,而每一類運行時庫又可再分為debug版和release版,因此Visual C++共提供了6個運行時庫。如下表:

C運行時庫 庫文件
Single thread(static link) ?libc.lib
Debug single thread(static link) ?libcd.lib
MultiThread(static link) ?libcmt.lib
Debug multiThread(static link) libcmtd.lib
MultiThread(dynamic link) msvert.lib
Debug multiThread(dynamic link) msvertd.lib?

  2.C運行時庫的作用

  C運行時庫除了給我們提供必要的庫函數調用(如memcpy、printf、malloc等)之外,它提供的另一個最重要的功能是為應用程序添加啟動函數。

  C運行時庫啟動函數的主要功能為進行程序的初始化,對全局變量進行賦初值,加載用戶程序的入口函數。

  不采用寬字符集的控制臺程序的入口點為mainCRTStartup(void)。下面我們以該函數為例來分析運行時庫究竟為我們添加了怎樣的入口程序。這個函數在crt0.c中被定義,下列的代碼經過了筆者的整理和簡化:

  • void mainCRTStartup(void)
  • {
  •  int mainret;
  •  /*獲得WIN32完整的版本信息*/
  •  _osver = GetVersion();
  •  _winminor = (_osver >> 8) & 0x00FF ;
  •  _winmajor = _osver & 0x00FF ;
  •  _winver = (_winmajor << 8) + _winminor;
  •  _osver = (_osver >> 16) & 0x00FFFF ;
  •  _ioinit(); /* initialize lowio */
  •  /* 獲得命令行信息 */
  •  _acmdln = (char *) GetCommandLineA();
  •  /* 獲得環境信息 */
  •  _aenvptr = (char *) __crtGetEnvironmentStringsA();
  •  _setargv(); /* 設置命令行參數 */
  •  _setenvp(); /* 設置環境參數 */
  •  _cinit(); /* C數據初始化:全局變量初始化,就在這里!*/
  •  __initenv = _environ;
  •  mainret = main( __argc, __argv, _environ ); /*調用main函數*/
  •  exit( mainret );
  • }
  • 復制代碼

    從以上代碼可知,運行庫在調用用戶程序的main或WinMain函數之前,進行了一些初始化工作。初始化完成后,接著才調用了我們編寫的main或WinMain函數。只有這樣,我們的C語言運行時庫和應用程序才能正常地工作起來。

      除了crt0.c外,C運行時庫中還包含wcrt0.c、 wincrt0.c、wwincrt0.c三個文件用來提供初始化函數。wcrt0.c是crt0.c的寬字符集版,wincrt0.c中包含 windows應用程序的入口函數,而wwincrt0.c則是wincrt0.c的寬字符集版。

      Visual C++的運行時庫源代碼缺省情況下不被安裝。如果您想查看其源代碼,則需要重裝Visual C++,并在重裝在時選中安裝運行庫源代碼選項。

      3.各種C運行時庫的區別

      (1)靜態鏈接的單線程庫

      靜態鏈接的單線程庫只能用于單線程的應用程序,C運行時庫的目標代碼最終被編譯在應用程序的二進制文件中。通過/ML編譯選項可以設置Visual C++使用靜態鏈接的單線程庫。

      (2)靜態鏈接的多線程庫

      靜態鏈接的多線程庫的目標代碼也最終被編譯在應用程序的二進制文件中,但是它可以在多線程程序中使用。通過/MD編譯選項可以設置Visual C++使用靜態鏈接的單線程庫。

      (3)動態鏈接的運行時庫

      動態鏈接的運行時庫將所有的C庫函數保存在一個單獨的動態鏈接庫MSVCRTxx.DLL中,MSVCRTxx.DLL處理了多線程問題。使用/ML編譯選項可以設置Visual C++使用動態鏈接的運行時庫。

      /MDd、 /MLd 或 /MTd 選項使用 Debug runtime library(調試版本的運行時刻函數庫),與/MD、 /ML 或 /MT分別對應。Debug版本的 Runtime Library 包含了調試信息,并采用了一些保護機制以幫助發現錯誤,加強了對錯誤的檢測,因此在運行性能方面比不上Release版本。

      下面看一個未正確使用C運行時庫的控制臺程序:

  • #include <stdio.h>
  • #include <afx.h>
  • int main()
  • {
  •  CFile file;
  •  CString str("I love you");
  •  TRY
  •  {
  •   file.Open("file.dat",CFile::modeWrite | CFile::modeCreate);
  •  }
  •  CATCH( CFileException, e )
  •  {
  •   #ifdef _DEBUG
  •   afxDump << "File could not be opened " << e->m_cause << "/n";
  •   #endif
  •  }
  •  END_CATCH
  •  file.Write(str,str.GetLength());
  •  file.Close();
  • }
  • 復制代碼

    我們在"rebuild all"的時候發生了link錯誤:

  • nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
  • nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
  • main.exe : fatal error LNK1120: 2 unresolved externals
  • Error executing cl.exe.
  • 復制代碼

    發 生錯誤的原因在于Visual C++對控制臺程序默認使用單線程的靜態鏈接庫,而MFC中的CFile類已暗藏了多線程。我們只需要在Visual C++6.0中依次點選Project->Settings->C/C++菜單和選項,在Project Options里修改編譯選項即可。

    C 運行時庫是微軟?對 標準C庫函數的實現,因為當時考慮到許多程序都使用C編寫,而這些程序都要使用標準的C庫,按照以前的方式每一個程序最終都要拷貝一份標準庫的實現到程序 中,這樣同一時刻內存中可能有許多份標準庫的代碼(一個程序一份),所以微軟出于效率的考慮把 ?標準C庫做為動態鏈接來實現,這樣多個程序使用C標準庫時內存中就只有一份拷貝了。(對每一個程序來說,它相當于自己擁有一份,? ?對于標準庫中的全局變量也做了處理的,不會因為共享同一份代碼而出現沖突)。? ?這也算是對C標準庫的一個擴展吧,至于說靜態鏈接的時候仍然把它叫做運行時庫那只能說這是個習慣問題而已了。??
    ?
    ?運行時庫和普通的? ?dll? ?一樣,如果有程序用到了才會加載,沒有程序使用的時候不會駐留內存的。話雖如此,但有多少系統的東西說不定也是用C寫的,這些東西的存在就使C運行時庫存在于內存中了

    從字面上看,運行庫是程序在運行時所需要的庫文件。通常運行庫是以DLL形式提供的。 Delphi和C++ Builder的運行庫為.bpl文件,實際還是一個DLL。運行庫中一般包括編程時常用的函數,如字符串操作、文件操作、界面等內容。不同的語言所支持 的函數通常是不同的,所以使用的庫也是完全不同的,這就是為什么有VB運行庫、C運行庫、Delphi運行庫之分的原因。即使都是C++語言,也可能因為 提供的函數不同,而使用不同的庫。如VC++使用的運行庫和C++ Builder就完全不同。
    如果不使用運行庫,每個程序中都會包括很多重復的代碼,而使用運行庫,可以大大縮小編譯后的程序的大小。但另一方面,由于使用了運行庫,所以在分發程序時就必須帶有這些庫,比較麻煩。如果在操作系統中找不到相應的運行庫程序就無法運行。為了解決這個矛盾,Windows?總 是會帶上它自己開發的軟件的最新的運行庫。象Windows 2000以后的版本都包括Visual Basic 5.0/6.0的庫。Internet Explorer總是帶有最新的Visual C++ 6.0的庫。Windows XP帶有Microsoft .NET 1.0(用于VB.NET和C#)的庫。Visual C++、Delphi和C++ Builder允許用戶選擇所編譯得到的程序是否依賴于運行庫。而VB、FoxPro、PowerBuilder、LabWindows/CVI和 Matlab就不允許用戶進行這種選擇,必須依賴于運行庫。

    2 內存泄漏

    2.1 C++中動態內存分配引發問題的解決方案

    假設我們要開發一個String類,它可以方便地處理字符串數據。我們可以在類中聲明一個數組,考慮到有時候字符串極長,我們可以把數組大小設為200, 但一般的情況下又不需要這么多的空間,這樣是浪費了內存。對了,我們可以使用new操作符,這樣是十分靈活的,但在類中就會出現許多意想不到的問題,本文 就是針對這一現象而寫的。現在,我們先來開發一個String類,但它是一個不完善的類。的確,我們要刻意地使它出現各種各樣的問題,這樣才好對癥下藥。 好了,我們開始吧!

  • /* String.h */
  • #ifndef STRING_H_
  • #define STRING_H_
  • class String
  • {
  • private:
  • char * str; //存儲數據
  • int len; //字符串長度
  • public:
  • String(const char * s); //構造函數
  • String(); // 默認構造函數
  • ~String(); // 析構函數
  • friend ostream & operator<<(ostream & os,const String& st);
  • };
  • #endif
  • 復制代碼
  • /*String.cpp*/
  • #include <iostream>
  • #include <cstring>
  • #include "String.h"
  • using namespace std;
  • String::String(const char * s)
  • {
  • len = strlen(s);
  • str = new char[len + 1];
  • strcpy(str, s);
  • }//拷貝數據
  • String::String()
  • {
  • len =0;
  • str = new char[len+1];
  • str[0]='"0';
  • }
  • String::~String()
  • {
  • cout<<"這個字符串將被刪除:"<<str<<'"n';//為了方便觀察結果,特留此行代碼。
  • delete [] str;
  • }
  • ostream & operator<<(ostream & os, const String & st)
  • {
  • os << st.str;
  • return os;
  • }
  • 復制代碼
  • /*test_right.cpp*/
  • #include <iostream>
  • #include <stdlib.h>
  • #include "String.h"
  • using namespace std;
  • int main()
  • {
  • String temp("大家網");
  • cout<<temp<<'"n';
  • system("PAUSE");
  • return 0;
  • }
  • 復制代碼

    運行結果:

      大家網

      請按任意鍵繼續. . .

      大家可以看到,以上程序十分正確,而且也是十分有用的。可是,我們不能被表面現象所迷惑!下面,請大家用test_String.cpp文件替換test_right.cpp文件進行編譯,看看結果。有的編譯器可能就是根本不能進行編譯!

  • /*test_String.cpp:*/
  • #include <iostream>
  • #include <stdlib.h>
  • #include "String.h"
  • using namespace std;
  • void show_right(const String&);
  • void show_String(const String);//注意,參數非引用,而是按值傳遞。
  • int main()
  • {
  • String test1("第一個范例。");
  • String test2("第二個范例。");
  • String test3("第三個范例。");
  • String test4("第四個范例。");
  • cout<<"下面分別輸入三個范例:"n";
  • cout<<test1<<endl;
  • cout<<test2<<endl;
  • cout<<test3<<endl;
  • String* String1=new String(test1);
  • cout<<*String1<<endl;
  • delete String1;
  • cout<<test1<<endl; //在Dev-cpp上沒有任何反應。
  • cout<<"使用正確的函數:"<<endl;
  • show_right(test2);
  • cout<<test2<<endl;
  • cout<<"使用錯誤的函數:"<<endl;
  • show_String(test2);
  • cout<<test2<<endl; //這一段代碼出現嚴重的錯誤!
  • String String2(test3);
  • cout<<"String2: "<<String2<<endl;
  • String String3;
  • String3=test4;
  • cout<<"String3: "<<String3<<endl;
  • cout<<"下面,程序結束,析構函數將被調用。"<<endl;
  • return 0;
  • }
  • void show_right(const String& a)
  • {
  • cout<<a<<endl;
  • }
  • void show_String(const String a)
  • {
  • cout<<a<<endl;
  • }
  • 復制代碼

    運行結果:

      下面分別輸入三個范例:

      第一個范例。

      第二個范例。

      第三個范例。

      第一個范例。

      這個字符串將被刪除:第一個范例。

      使用正確的函數:

      

      第二個范例。

      第二個范例。

      使用錯誤的函數:

      第二個范例。

      這個字符串將被刪除:第二個范例。

      這個字符串將被刪除:?=

      ?=

      String2: 第三個范例。

      String3: 第四個范例。

      下面,程序結束,析構函數將被調用。

      這個字符串將被刪除:第四個范例。

      這個字符串將被刪除:第三個范例。

      這個字符串將被刪除:?=

      這個字符串將被刪除:x =

      這個字符串將被刪除:?=

      這個字符串將被刪除:


    現在,請大家自己試試運行結果,或許會更加慘不忍睹呢!下面,我為大家一一分析原因。

    首先,大家要知道,C++類有以下這些極為重要的函數:

    一:復制構造函數。

    二:賦值函數。

    我們先來講復制構造函數。什么是復制構造函數呢?比如,我們可以寫下這樣的代碼:String test1(test2);這是進行初始化。我們知道,初始化對象要用構造函數。可這兒呢?按理說,應該有聲明為這樣的構造函 數:String(const String &);可是,我們并沒有定義這個構造函數呀?答案是,C++提供了默認的復制構造函數,問題也就出在這兒。

    (1):什么時候會調用復制構造函數呢?(以String類為例。)

      在我們提供這樣的代碼:String test1(test2)時,它會被調用;當函數的參數列表為按值傳遞,也就是沒有用引用和指針作為類型時,如:void show_String(const String),它會被調用。其實,還有一些情況,但在這兒就不列舉了。

    (2):它是什么樣的函數。

    它的作用就是把兩個類進行復制。拿String類為例,C++提供的默認復制構造函數是這樣的:

  • String(const String& a)
  • {
  • str=a.str;
  • len=a.len;
  • }
  • 復制代碼

    在 平時,這樣并不會有任何的問題出現,但我們用了new操作符,涉及到了動態內存分配,我們就不得不談談淺復制和深復制了。以上的函數就是實行的淺復制,它 只是復制了指針,而并沒有復制指針指向的數據,可謂一點兒用也沒有。打個比方吧!就像一個朋友讓你把一個程序通過網絡發給他,而你大大咧咧地把快捷方式發 給了他,有什么用處呢?我們來具體談談:

    假如,A對象中存儲了這樣的字符串:“C++”。它的地址為2000。現在,我們把A對象賦給B對象:String B=A。現在,A和B對象的str指針均指向2000地址。看似可以使用,但如果B對象的析構函數被調用時,則地址2000處的字符串“C++”已經被從 內存中抹去,而A對象仍然指向地址2000。這時,如果我們寫下這樣的代碼:cout<<A<<endl;或是等待程序結束,A 對象的析構函數被調用時,A對象的數據能否顯示出來呢?只會是亂碼。而且,程序還會這樣做:連續對地址2000處使用兩次delete操作符,這樣的后果 是十分嚴重的!

    本例中,有這樣的代碼:

  • String* String1=new String(test1);
  • cout<<*String1<<endl;
  • delete String1;
  • 復制代碼

    假 設test1中str指向的地址為2000,而String中str指針同樣指向地址2000,我們刪除了2000處的數據,而test1對象呢?已經被 破壞了。大家從運行結果上可以看到,我們使用cout<<test1時,一點反應也沒有。而在test1的析構函數被調用時,顯示是這樣: “這個字符串將被刪除:”。

    再看看這段代碼:

  • cout<<"使用錯誤的函數:"<<endl;
  • show_String(test2);
  • cout<<test2<<endl;//這一段代碼出現嚴重的錯誤!
  • 復制代碼

    show_String 函數的參數列表void show_String(const String a)是按值傳遞的,所以,我們相當于執行了這樣的代碼:String a=test2;函數執行完畢,由于生存周期的緣故,對象a被析構函數刪除,我們馬上就可以看到錯誤的顯示結果了:這個字符串將被刪除:?=。當 然,test2也被破壞了。解決的辦法很簡單,當然是手工定義一個復制構造函數嘍!人力可以勝天!

  • String::String(const String& a)
  • {
  • len=a.len;
  • str=new char(len+1);
  • strcpy(str,a.str);
  • }
  • 復制代碼

    我 們執行的是深復制。這個函數的功能是這樣的:假設對象A中的str指針指向地址2000,內容為“I am a C++ Boy!”。我們執行代碼String B=A時,我們先開辟出一塊內存,假設為3000。我們用strcpy函數將地址2000的內容拷貝到地址3000中,再將對象B的str指針指向地址 3000。這樣,就互不干擾了。

    大家把這個函數加入程序中,問題就解決了大半,但還沒有完全解決,問題在賦值函數上。我們的程序中有這樣的段代碼:

  • String String3;
  • String3=test4;
  • 復制代碼

    經 過我前面的講解,大家應該也會對這段代碼進行尋根摸底:憑什么可以這樣做:String3=test4???原因是,C++為了用戶的方便,提供的這樣的 一個操作符重載函數:operator=。所以,我們可以這樣做。大家應該猜得到,它同樣是執行了淺復制,出了同樣的毛病。比如,執行了這段代碼后,析構 函數開始大展神威^_^。由于這些變量是后進先出的,所以最后的String3變量先被刪除:這個字符串將被刪除:第四個范例。很正常。最后,刪除到 test4的時候,問題來了:這個字符串將被刪除:?=。原因我不用贅述了,只是這個賦值函數怎么寫,還有一點兒學問呢!大家請看:

    平時,我們可以寫這樣的代碼:x=y=z。(均為整型變量。)而在類對象中,我們同樣要這樣,因為這很方便。而對象A=B=C就是 A.operator=(B.operator=(c))。而這個operator=函數的參數列表應該是:const String& a,所以,大家不難推出,要實現這樣的功能,返回值也要是String&,這樣才能實現A=B=C。我們先來寫寫看:

  • String& String::operator=(const String& a)
  • {
  • delete [] str;//先刪除自身的數據
  • len=a.len;
  • str=new char[len+1];
  • strcpy(str,a.str);//此三行為進行拷貝
  • return *this;//返回自身的引用
  • }
  • 復制代碼

    是 不是這樣就行了呢?我們假如寫出了這種代碼:A=A,那么大家看看,豈不是把A對象的數據給刪除了嗎?這樣可謂引發一系列的錯誤。所以,我們還要檢查是否 為自身賦值。只比較兩對象的數據是不行了,因為兩個對象的數據很有可能相同。我們應該比較地址。以下是完好的賦值函數:

  • String& String::operator=(const String& a)
  • {
  • if(this==&a)
  • return *this;
  • delete [] str;
  • len=a.len;
  • str=new char[len+1];
  • strcpy(str,a.str);
  • return *this;
  • }
  • 復制代碼

    把這些代碼加入程序,問題就完全解決,下面是運行結果:

      下面分別輸入三個范例:

      第一個范例

      第二個范例

      第三個范例

      第一個范例

      這個字符串將被刪除:第一個范例。

      第一個范例

       使用正確的函數:

      第二個范例。

      第二個范例。

       使用錯誤的函數:

      第二個范例。

      這個字符串將被刪除:第二個范例。

      第二個范例。

      String2: 第三個范例。

      String3: 第四個范例。

      下面,程序結束,析構函數將被調用。

      這個字符串將被刪除:第四個范例。

      這個字符串將被刪除:第三個范例。

      這個字符串將被刪除:第四個范例。

      這個字符串將被刪除:第三個范例。

      這個字符串將被刪除:第二個范例。

      這個字符串將被刪除:第一個范例。


    2.2 如何對付內存泄漏?

    寫出那些不會導致任何內存泄漏的代碼。很明顯,當你的代碼中到處充滿了new 操作、delete操作和指針運算的話,你將會在某個地方搞暈了頭,導致內存泄漏,指針引用錯誤,以及諸如此類的問題。這和你如何小心地對待內存分配工作 其實完全沒有關系:代碼的復雜性最終總是會超過你能夠付出的時間和努力。于是隨后產生了一些成功的技巧,它們依賴于將內存分配(allocations) 與重新分配(deallocation)工作隱藏在易于管理的類型之后。標準容器(standard containers)是一個優秀的例子。它們不是通過你而是自己為元素管理內存,從而避免了產生糟糕的結果。想象一下,沒有string和vector 的幫助,寫出這個:

  • #include<vector>
  • #include<string>
  • #include<iostream>
  • #include<algorithm>
  • using namespace std;
  • int main() // small program messing around with strings
  • {
  •  cout << "enter some whitespace-separated words:"n";
  •  vector<string> v;
  •  string s;
  •  while (cin>>s) v.push_back(s);
  •  sort(v.begin(),v.end());
  •  string cat;
  •  typedef vector<string>::const_iterator Iter;
  •  for (Iter p = v.begin(); p!=v.end(); ++p) cat += *p+"+";
  •  cout << cat << ’"n’;
  • }
  • 復制代碼

    你有多少機會在第一次就得到正確的結果?你又怎么知道你沒有導致內存泄漏呢?

      注意,沒有出現顯式的內存管理,宏,造型,溢出檢查,顯式的長度限制,以及指針。通過使用函數對象和標準算法(standard algorithm),我可以避免使用指針——例如使用迭代子(iterator),不過對于一個這么小的程序來說有點小題大作了。

      這些技巧并不完美,要系統化地使用它們也并不總是那么容易。但是,應用它們產生了驚人的差異,而且通過減少顯式的內存分配與重新分配的次數,你甚至可 以使余下的例子更加容易被跟蹤。早在1981年,我就指出,通過將我必須顯式地跟蹤的對象的數量從幾萬個減少到幾打,為了使程序正確運行而付出的努力從可 怕的苦工,變成了應付一些可管理的對象,甚至更加簡單了。

      如果你的程序還沒有包含將顯式內存管理減少到最小限度的庫,那么要讓你程序完成和正確運行的話,最快的途徑也許就是先建立一個這樣的庫。

      模板和標準庫實現了容器、資源句柄以及諸如此類的東西,更早的使用甚至在多年以前。異常的使用使之更加完善。

      如果你實在不能將內存分配/重新分配的操作隱藏到你需要的對象中時,你可以使用資源句柄(resource handle),以將內存泄漏的可能性降至最低。這里有個例子:我需要通過一個函數,在空閑內存中建立一個對象并返回它。這時候可能忘記釋放這個對象。畢 竟,我們不能說,僅僅關注當這個指針要被釋放的時候,誰將負責去做。使用資源句柄,這里用了標準庫中的auto_ptr,使需要為之負責的地方變得明確 了。

  • #include<memory>
  • #include<iostream>
  • using namespace std;
  • struct S {
  •  S() { cout << "make an S"n"; }
  •  ~S() { cout << "destroy an S"n"; }
  •  S(const S&) { cout << "copy initialize an S"n"; }
  •  S& operator=(const S&) { cout << "copy assign an S"n"; }
  • };
  • S* f()
  • {
  •  return new S; // 誰該負責釋放這個S?
  • };
  • auto_ptr<S> g()
  • {
  •  return auto_ptr<S>(new S); // 顯式傳遞負責釋放這個S
  • }
  • int main()
  • {
  •  cout << "start main"n";
  •  S* p = f();
  •  cout << "after f() before g()"n";
  •  // S* q = g(); // 將被編譯器捕捉
  •  auto_ptr<S> q = g();
  •  cout << "exit main"n";
  •  // *p產生了內存泄漏
  •  // *q被自動釋放
  • }
  • 復制代碼

    在更一般的意義上考慮資源,而不僅僅是內存。

    如果在你的環境中不能系統地應用這些技巧(例如,你必須使用別的地方的代碼,或者你的程序的另一部分簡直是原始人類(譯注:原文是 Neanderthals,尼安德特人,舊石器時代廣泛分布在歐洲的猿人)寫的,如此等等),那么注意使用一個內存泄漏檢測器作為開發過程的一部分,或者 插入一個垃圾收集器(garbage collector)。

    2.3淺談C/C++內存泄漏及其檢測工具

      對于一個c/c++程序員來說,內存泄漏是一個常見的也是令人頭疼的問題。已經有許多技術被研究出來以應對這個問題,比如Smart Pointer,Garbage Collection等。Smart Pointer技術比較成熟,STL中已經包含支持Smart Pointer的class,但是它的使用似乎并不廣泛,而且它也不能解決所有的問題;Garbage Collection技術在Java中已經比較成熟,但是在c/c++領域的發展并不順暢,雖然很早就有人思考在C++中也加入GC的支持。現實世界就是 這樣的,作為一個c/c++程序員,內存泄漏是你心中永遠的痛。不過好在現在有許多工具能夠幫助我們驗證內存泄漏的存在,找出發生問題的代碼。

    2.3.1 內存泄漏的定義

    一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的(內存塊的大小可以在程序運行期決定),使用完后必須顯示釋放的內存。 應用程序一般使用malloc,realloc,new等函數從堆中分配到一塊內存,使用完后,程序必須負責相應的調用free或delete釋放該內存 塊,否則,這塊內存就不能被再次使用,我們就說這塊內存泄漏了。以下這段小程序演示了堆內存發生泄漏的情形:

  • void MyFunction(int nSize)
  • {
  •  char* p= new char[nSize];
  •  if( !GetStringFrom( p, nSize ) ){
  •   MessageBox(“Error”);
  •   return;
  •  }
  •  …//using the string pointed by p;
  •  delete p;
  • }
  • 復制代碼

    當函數GetStringFrom()返回零的時候,指針p指向的內存就不會被釋放。這是一種常見的發生內存泄漏的情形。程序在入口處分配內存,在出口處釋放內存,但是c函數可以在任何地方退出,所以一旦有某個出口處沒有釋放應該釋放的內存,就會發生內存泄漏。

      廣義的說,內存泄漏不僅僅包含堆內存的泄漏,還包含系統資源的泄漏(resource leak),比如核心態HANDLE,GDI Object,SOCKET, Interface等,從根本上說這些由操作系統分配的對象也消耗內存,如果這些對象發生泄漏最終也會導致內存的泄漏。而且,某些對象消耗的是核心態內 存,這些對象嚴重泄漏時會導致整個操作系統不穩定。所以相比之下,系統資源的泄漏比堆內存的泄漏更為嚴重。

    GDI Object的泄漏是一種常見的資源泄漏:

  • void CMyView::OnPaint( CDC* pDC )
  • {
  •  CBitmap bmp;
  •  CBitmap* pOldBmp;
  •  bmp.LoadBitmap(IDB_MYBMP);
  •  pOldBmp = pDC->SelectObject( &bmp );
  •  …
  •  if( Something() ){
  •   return;
  •  }
  •  pDC->SelectObject( pOldBmp );
  •  return;
  • }
  • 復制代碼

    當 函數Something()返回非零的時候,程序在退出前沒有把pOldBmp選回pDC中,這會導致pOldBmp指向的HBITMAP對象發生泄漏。 這個程序如果長時間的運行,可能會導致整個系統花屏。這種問題在Win9x下比較容易暴露出來,因為Win9x的GDI堆比Win2k或NT 的要小很多。

    2.3.2 內存泄漏的發生方式

      以發生的方式來分類,內存泄漏可以分為4類:

      1. 常發性內存泄漏。發生內存泄漏的代碼會被多次執行到,每次被執行的時候都會導致一塊內存泄漏。比如例二,如果Something()函數一直返回True,那么pOldBmp指向的HBITMAP對象總是發生泄漏。

      2. 偶發性內存泄漏。發生內存泄漏的代碼只有在某些特定環境或操作過程下才會發生。比如例二,如果Something()函數只有在特定環境下才返回 True,那么pOldBmp指向的HBITMAP對象并不總是發生泄漏。常發性和偶發性是相對的。對于特定的環境,偶發性的也許就變成了常發性的。所以 測試環境和測試方法對檢測內存泄漏至關重要。

    3. 一次性內存泄漏。發生內存泄漏的代碼只會被執行一次,或者由于算法上的缺陷,導致總會有一塊僅且一塊內存發生泄漏。比如,在類的構造函數中分配內存,在析構函數中卻沒有釋放該內存,但是因為這個類是一個Singleton,所以內存泄漏只會發生一次。另一個例子:

  • char* g_lpszFileName = NULL;
  • void SetFileName( const char* lpcszFileName )
  • {
  •  if( g_lpszFileName ){
  •   free( g_lpszFileName );
  •  }
  •  g_lpszFileName = strdup( lpcszFileName );
  • }
  • 復制代碼

    如果程序在結束的時候沒有釋放g_lpszFileName指向的字符串,那么,即使多次調用SetFileName(),總會有一塊內存,而且僅有一塊內存發生泄漏。

    4. 隱式內存泄漏。程序在運行過程中不停的分配內存,但是直到結束的時候才釋放內存。嚴格的說這里并沒有發生內存泄漏,因為最終程序釋放了所有申請的內存。但 是對于一個服務器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內存也可能導致最終耗盡系統的所有內存。所以,我們稱這類內存泄漏為隱式內存泄漏。舉一 個例子:

  • class Connection
  • {
  •  public:
  •   Connection( SOCKET s);
  •   ~Connection();
  •   …
  •  private:
  •   SOCKET _socket;
  •   …
  • };
  • class ConnectionManager
  • {
  •  public:
  •   ConnectionManager(){}
  •   ~ConnectionManager(){
  •    list::iterator it;
  •    for( it = _connlist.begin(); it != _connlist.end(); ++it ){
  •     delete (*it);
  •    }
  •    _connlist.clear();
  •   }
  •   void OnClientConnected( SOCKET s ){
  •    Connection* p = new Connection(s);
  •    _connlist.push_back(p);
  •   }
  •   void OnClientDisconnected( Connection* pconn ){
  •    _connlist.remove( pconn );
  •    delete pconn;
  •   }
  •  private:
  •   list _connlist;
  • };
  • 復制代碼

    假 設在Client從Server端斷開后,Server并沒有呼叫OnClientDisconnected()函數,那么代表那次連接的 Connection對象就不會被及時的刪除(在Server程序退出的時候,所有Connection對象會在ConnectionManager的析 構函數里被刪除)。當不斷的有連接建立、斷開時隱式內存泄漏就發生了。

    從用戶使用程序的角度來看,內存泄漏本身不會產生什么危害,作為一般的用戶,根本感覺不到內存泄漏的存在。真正有危害的是內存泄漏的堆積,這會最終消耗盡 系統所有的內存。從這個角度來說,一次性內存泄漏并沒有什么危害,因為它不會堆積,而隱式內存泄漏危害性則非常大,因為較之于常發性和偶發性內存泄漏它更 難被檢測到。

    2.3.3 檢測內存泄漏

      檢測內存泄漏的關鍵是要能截獲住對分配內存和釋放內存的函數的調用。截獲住這兩個函數,我們就能跟蹤每一塊內存的生命周期,比如,每當成功的分配一塊 內存后,就把它的指針加入一個全局的list中;每當釋放一塊內存,再把它的指針從list中刪除。這樣,當程序結束的時候,list中剩余的指針就是指 向那些沒有被釋放的內存。這里只是簡單的描述了檢測內存泄漏的基本原理,詳細的算法可以參見Steve Maguire的<<Writing Solid Code>>。

      如果要檢測堆內存的泄漏,那么需要截獲住malloc/realloc/free和new/delete就可以了(其實new/delete最終也是 用malloc/free的,所以只要截獲前面一組即可)。對于其他的泄漏,可以采用類似的方法,截獲住相應的分配和釋放函數。比如,要檢測 BSTR的泄漏,就需要截獲SysAllocString/SysFreeString;要檢測HMENU的泄漏,就需要截獲CreateMenu/ DestroyMenu。(有的資源的分配函數有多個,釋放函數只有一個,比如,SysAllocStringLen也可以用來分配BSTR,這時就需要 截獲多個分配函數)

      在Windows平臺下,檢測內存泄漏的工具常用的一般有三種,MS C-Runtime Library內建的檢測功能;外掛式的檢測工具,諸如,Purify,BoundsChecker等;利用Windows NT自帶的Performance Monitor。這三種工具各有優缺點,MS C-Runtime Library雖然功能上較之外掛式的工具要弱,但是它是免費的;Performance Monitor雖然無法標示出發生問題的代碼,但是它能檢測出隱式的內存泄漏的存在,這是其他兩類工具無能為力的地方。

      以下我們詳細討論這三種檢測工具:

    2.3.3.1 VC下內存泄漏的檢測方法

      用MFC開發的應用程序,在DEBUG版模式下編譯后,都會自動加入內存泄漏的檢測代碼。在程序結束后,如果發生了內存泄漏,在Debug窗口中會顯示出所有發生泄漏的內存塊的信息,以下兩行顯示了一塊被泄漏的內存塊的信息:

    E:"TestMemLeak"TestDlg.cpp(70) : {59} normal block at 0x00881710, 200 bytes long.

    Data: <abcdefghijklmnop> 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70

      第一行顯示該內存塊由TestDlg.cpp文件,第70行代碼分配,地址在0x00881710,大小為200字節,{59}是指調用內存分配函數 的Request Order,關于它的詳細信息可以參見MSDN中_CrtSetBreakAlloc()的幫助。第二行顯示該內存塊前16個字節的內容,尖括號內是以 ASCII方式顯示,接著的是以16進制方式顯示。

      一般大家都誤以為這些內存泄漏的檢測功能是由MFC提供的,其實不然。MFC只是封裝和利用了MS C-Runtime Library的Debug Function。非MFC程序也可以利用MS C-Runtime Library的Debug Function加入內存泄漏的檢測功能。MS C-Runtime Library在實現malloc/free,strdup等函數時已經內建了內存泄漏的檢測功能。

    注意觀察一下由MFC Application Wizard生成的項目,在每一個cpp文件的頭部都有這樣一段宏定義:

  • #ifdef _DEBUG
  • #define new DEBUG_NEW
  • #undef THIS_FILE
  • static char THIS_FILE[] = __FILE__;
  • #endif
  • 復制代碼

    有了這樣的定義,在編譯DEBUG版時,出現在這個cpp文件中的所有new都被替換成DEBUG_NEW了。那么DEBUG_NEW是什么呢?DEBUG_NEW也是一個宏,以下摘自afx.h,1632行

  • #define DEBUG_NEW new(THIS_FILE, __LINE__)
  • 復制代碼

    所以如果有這樣一行代碼:

  • char* p = new char[200];
  • 復制代碼

    經過宏替換就變成了:

  • char* p = new( THIS_FILE, __LINE__)char[200];
  • 復制代碼

    根據C++的標準,對于以上的new的使用方法,編譯器會去找這樣定義的operator new:

  • void* operator new(size_t, LPCSTR, int)
  • 復制代碼

    我們在afxmem.cpp 63行找到了一個這樣的operator new 的實現

  • void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
  • {
  •  return ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine);
  • }
  • void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
  • {
  •  …
  •  pResult = _malloc_dbg(nSize, nType, lpszFileName, nLine);
  •  if (pResult != NULL)
  •   return pResult;
  •  …
  • }
  • 復制代碼

    第 二個operator new函數比較長,為了簡單期間,我只摘錄了部分。很顯然最后的內存分配還是通過_malloc_dbg函數實現的,這個函數屬于MS C-Runtime Library 的Debug Function。這個函數不但要求傳入內存的大小,另外還有文件名和行號兩個參數。文件名和行號就是用來記錄此次分配是由哪一段代碼造成的。如果這塊內 存在程序結束之前沒有被釋放,那么這些信息就會輸出到Debug窗口里。

      這里順便提一下THIS_FILE,__FILE和__LINE__。__FILE__和__LINE__都是編譯器定義的宏。當碰到 __FILE__時,編譯器會把__FILE__替換成一個字符串,這個字符串就是當前在編譯的文件的路徑名。當碰到__LINE__時,編譯器會把 __LINE__替換成一個數字,這個數字就是當前這行代碼的行號。在DEBUG_NEW的定義中沒有直接使用__FILE__,而是用了 THIS_FILE,其目的是為了減小目標文件的大小。假設在某個cpp文件中有100處使用了new,如果直接使用__FILE__,那編譯器會產生 100個常量字符串,這100個字符串都是飧?/SPAN>cpp文件的路徑名,顯然十分冗余。如果使用THIS_FILE,編譯器只會產生一個常 量字符串,那100處new的調用使用的都是指向常量字符串的指針。

      再次觀察一下由MFC Application Wizard生成的項目,我們會發現在cpp文件中只對new做了映射,如果你在程序中直接使用malloc函數分配內存,調用malloc的文件名和行 號是不會被記錄下來的。如果這塊內存發生了泄漏,MS C-Runtime Library仍然能檢測到,但是當輸出這塊內存塊的信息,不會包含分配它的的文件名和行號。

    要在非MFC程序中打開內存泄漏的檢測功能非常容易,你只要在程序的入口處加入以下幾行代碼:

  • int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
  • tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
  • _CrtSetDbgFlag( tmpFlag );
  • 復制代碼

    這樣,在程序結束的時候,也就是winmain,main或dllmain函數返回之后,如果還有內存塊沒有釋放,它們的信息會被打印到Debug窗口里。

    如果你試著創建了一個非MFC應用程序,而且在程序的入口處加入了以上代碼,并且故意在程序中不釋放某些內存塊,你會在Debug窗口里看到以下的信息:

    {47} normal block at 0x00C91C90, 200 bytes long.

    Data: < > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F


      內存泄漏的確檢測到了,但是和上面MFC程序的例子相比,缺少了文件名和行號。對于一個比較大的程序,沒有這些信息,解決問題將變得十分困難。

      為了能夠知道泄漏的內存塊是在哪里分配的,你需要實現類似MFC的映射功能,把new,maolloc等函數映射到_malloc_dbg函數上。這里我不再贅述,你可以參考MFC的源代碼。

      由于Debug Function實現在MS C-RuntimeLibrary中,所以它只能檢測到堆內存的泄漏,而且只限于malloc,realloc或strdup等分配的內存,而那些系統資 源,比如HANDLE,GDI Object,或是不通過C-Runtime Library分配的內存,比如VARIANT,BSTR的泄漏,它是無法檢測到的,這是這種檢測法的一個重大的局限性。另外,為了能記錄內存塊是在哪里 分配的,源代碼必須相應的配合,這在調試一些老的程序非常麻煩,畢竟修改源代碼不是一件省心的事,這是這種檢測法的另一個局限性。

    對于開發一個大型的程序,MS C-Runtime Library提供的檢測功能是遠遠不夠的。接下來我們就看看外掛式的檢測工具。我用的比較多的是BoundsChecker,一則因為它的功能比較全 面,更重要的是它的穩定性。這類工具如果不穩定,反而會忙里添亂。到底是出自鼎鼎大名的NuMega,我用下來基本上沒有什么大問題。

    2.3.3.2 使用BoundsChecker檢測內存泄漏

      BoundsChecker采用一種被稱為 Code Injection的技術,來截獲對分配內存和釋放內存的函數的調用。簡單地說,當你的程序開始運行時,BoundsChecker的DLL被自動載入進 程的地址空間(這可以通過system-level的Hook實現),然后它會修改進程中對內存分配和釋放的函數調用,讓這些調用首先轉入它的代碼,然后 再執行原來的代碼。BoundsChecker在做這些動作的時,無須修改被調試程序的源代碼或工程配置文件,這使得使用它非常的簡便、直接。

      這里我們以malloc函數為例,截獲其他的函數方法與此類似。

      需要被截獲的函數可能在DLL中,也可能在程序的代碼里。比如,如果靜態連結C-Runtime Library,那么malloc函數的代碼會被連結到程序里。為了截獲住對這類函數的調用,BoundsChecker會動態修改這些函數的指令。

    以下兩段匯編代碼,一段沒有BoundsChecker介入,另一段則有BoundsChecker的介入:

    126: _CRTIMP void * __cdecl malloc (

    127: size_t nSize

    128: )

    129: {

    00403C10 push ebp

    00403C11 mov ebp,esp

    130: return _nh_malloc_dbg(nSize, _newmode, _NORMAL_BLOCK, NULL, 0);

    00403C13 push 0

    00403C15 push 0

    00403C17 push 1

    00403C19 mov eax,[__newmode (0042376c)]

    00403C1E push eax

    00403C1F mov ecx,dword ptr [nSize]

    00403C22 push ecx

    00403C23 call _nh_malloc_dbg (00403c80)

    00403C28 add esp,14h

    131: }


    以下這一段代碼有BoundsChecker介入:

    126: _CRTIMP void * __cdecl malloc (

    127: size_t nSize

    128: )

    129: {

    00403C10 jmp 01F41EC8

    00403C15 push 0

    00403C17 push 1

    00403C19 mov eax,[__newmode (0042376c)]

    00403C1E push eax

    00403C1F mov ecx,dword ptr [nSize]

    00403C22 push ecx

    00403C23 call _nh_malloc_dbg (00403c80)

    00403C28 add esp,14h

    131: }


      當BoundsChecker介入后,函數malloc的前三條匯編指令被替換成一條jmp指令,原來的三條指令被搬到地址01F41EC8處了。當 程序進入malloc后先jmp到01F41EC8,執行原來的三條指令,然后就是BoundsChecker的天下了。大致上它會先記錄函數的返回地址 (函數的返回地址在stack上,所以很容易修改),然后把返回地址指向屬于BoundsChecker的代碼,接著跳到malloc函數原來的指令,也 就是在00403c15的地方。當malloc函數結束的時候,由于返回地址被修改,它會返回到BoundsChecker的代碼中,此時 BoundsChecker會記錄由malloc分配的內存的指針,然后再跳轉到到原來的返回地址去。

      如果內存分配/釋放函數在DLL中,BoundsChecker則采用另一種方法來截獲對這些函數的調用。BoundsChecker通過修改程序的DLL Import Table讓table中的函數地址指向自己的地址,以達到截獲的目的。

    截獲住這些分配和釋放函數,BoundsChecker就能記錄被分配的內存或資源的生命周期。接下來的問題是如何與源代碼相關,也就是說當 BoundsChecker檢測到內存泄漏,它如何報告這塊內存塊是哪段代碼分配的。答案是調試信息(Debug Information)。當我們編譯一個Debug版的程序時,編譯器會把源代碼和二進制代碼之間的對應關系記錄下來,放到一個單獨的文件里 (.pdb)或者直接連結進目標程序,通過直接讀取調試信息就能得到分配某塊內存的源代碼在哪個文件,哪一行上。使用Code Injection和Debug Information,使BoundsChecker不但能記錄呼叫分配函數的源代碼的位置,而且還能記錄分配時的Call Stack,以及Call Stack上的函數的源代碼位置。這在使用像MFC這樣的類庫時非常有用,以下我用一個例子來說明:

    void ShowXItemMenu()
    {
     …
     CMenu menu;
     menu.CreatePopupMenu();
     //add menu items.
     menu.TrackPropupMenu();
     …
    }

    void ShowYItemMenu( )
    {
     …
     CMenu menu;
     menu.CreatePopupMenu();
     //add menu items.
     menu.TrackPropupMenu();
     menu.Detach();//this will cause HMENU leak
     …
    }

    BOOL CMenu::CreatePopupMenu()
    {
     …
     hMenu = CreatePopupMenu();
     …
    }

    當調用ShowYItemMenu()時,我們故意造成HMENU的泄漏。但是,對于BoundsChecker來說被泄漏的HMENU是在 class CMenu::CreatePopupMenu()中分配的。假設的你的程序有許多地方使用了CMenu的CreatePopupMenu()函數,如 CMenu::CreatePopupMenu()造成的,你依然無法確認問題的根結到底在哪里,在ShowXItemMenu()中還是在 ShowYItemMenu()中,或者還有其它的地方也使用了CreatePopupMenu()?有了Call Stack的信息,問題就容易了。BoundsChecker會如下報告泄漏的HMENU的信息:

    Function

    File

    Line

    CMenu::CreatePopupMenu

    E:"8168"vc98"mfc"mfc"include"afxwin1.inl

    1009

    ShowYItemMenu

    E:"testmemleak"mytest.cpp

    100


      這里省略了其他的函數調用

      如此,我們很容易找到發生問題的函數是ShowYItemMenu()。當使用MFC之類的類庫編程時,大部分的API調用都被封裝在類庫的class里,有了Call Stack信息,我們就可以非常容易的追蹤到真正發生泄漏的代碼。

      記錄Call Stack信息會使程序的運行變得非常慢,因此默認情況下BoundsChecker不會記錄Call Stack信息。可以按照以下的步驟打開記錄Call Stack信息的選項開關:

      1. 打開菜單:BoundsChecker|Setting…

      2. 在Error Detection頁中,在Error Detection Scheme的List中選擇Custom

      3. 在Category的Combox中選擇 Pointer and leak error check

      4. 鉤上Report Call Stack復選框

      5. 點擊Ok

      基于Code Injection,BoundsChecker還提供了API Parameter的校驗功能,memory over run等功能。這些功能對于程序的開發都非常有益。由于這些內容不屬于本文的主題,所以不在此詳述了。

    盡管BoundsChecker的功能如此強大,但是面對隱式內存泄漏仍然顯得蒼白無力。所以接下來我們看看如何用Performance Monitor檢測內存泄漏。

    2.3.3.3 使用Performance Monitor檢測內存泄漏
      NT的內核在設計過程中已經加入了系統監視功能,比如CPU 的使用率,內存的使用情況,I/O操作的頻繁度等都作為一個個Counter,應用程序可以通過讀取這些Counter了解整個系統的或者某個進程的運行 狀況。Performance Monitor就是這樣一個應用程序。

      為了檢測內存泄漏,我們一般可以監視Process對象的Handle Count,Virutal Bytes 和Working Set三個Counter。Handle Count記錄了進程當前打開的HANDLE的個數,監視這個Counter有助于我們發現程序是否有Handle泄漏;Virtual Bytes記錄了該進程當前在虛地址空間上使用的虛擬內存的大小,NT的內存分配采用了兩步走的方法,首先,在虛地址空間上保留一段空間,這時操作系統并 沒有分配物理內存,只是保留了一段地址。然后,再提交這段空間,這時操作系統才會分配物理內存。所以,Virtual Bytes一般總大于程序的Working Set。監視Virutal Bytes可以幫助我們發現一些系統底層的問題; Working Set記錄了操作系統為進程已提交的內存的總量,這個值和程序申請的內存總量存在密切的關系,如果程序存在內存的泄漏這個值會持續增加,但是 Virtual Bytes卻是跳躍式增加的。

      監視這些Counter可以讓我們了解進程使用內存的情況,如果發生了泄漏,即使是隱式內存泄漏,這些Counter的值也會持續增加。但是,我們知 道有問題卻不知道哪里有問題,所以一般使用Performance Monitor來驗證是否有內存泄漏,而使用BoundsChecker來找到和解決。

      當Performance Monitor顯示有內存泄漏,而BoundsChecker卻無法檢測到,這時有兩種可能:第一種,發生了偶發性內存泄漏。這時你要確保使用 Performance Monitor和使用BoundsChecker時,程序的運行環境和操作方法是一致的。第二種,發生了隱式的內存泄漏。這時你要重新審查程序的設計,然 后仔細研究Performance Monitor記錄的Counter的值的變化圖,分析其中的變化和程序運行邏輯的關系,找到一些可能的原因。這是一個痛苦的過程,充滿了假設、猜想、驗 證、失敗,但這也是一個積累經驗的絕好機會。

    3 探討C++內存回收

    3.1 C++內存對象大會戰

      如果一個人自稱為程序高手,卻對內存一無所知,那么我可以告訴你,他一定在吹牛。用C或C++寫程序,需要更多地關注內存,這不僅僅是因為內存的分配 是否合理直接影響著程序的效率和性能,更為主要的是,當我們操作內存的時候一不小心就會出現問題,而且很多時候,這些問題都是不易發覺的,比如內存泄漏, 比如懸掛指針。筆者今天在這里并不是要討論如何避免這些問題,而是想從另外一個角度來認識C++內存對象。

      我們知道,C++將內存劃分為三個邏輯區域:堆、棧和靜態存儲區。既然如此,我稱位于它們之中的對象分別為堆對象,棧對象以及靜態對象。那么這些不同的內存對象有什么區別了?堆對象和棧對象各有什么優劣了?如何禁止創建堆對象或棧對象了?這些便是今天的主題。

    3.1.1 基本概念

      先來看看棧。棧,一般用于存放局部變量或對象,如我們在函數定義中用類似下面語句聲明的對象:

  • Type stack_object;
  • 復制代碼

    stack_object便是一個棧對象,它的生命期是從定義點開始,當所在函數返回時,生命結束。

      另外,幾乎所有的臨時對象都是棧對象。比如,下面的函數定義:

  • Type fun(Type object);
  • 復制代碼

    這 個函數至少產生兩個臨時對象,首先,參數是按值傳遞的,所以會調用拷貝構造函數生成一個臨時對象object_copy1 ,在函數內部使用的不是使用的不是object,而是object_copy1,自然,object_copy1是一個棧對象,它在函數返回時被釋放;還 有這個函數是值返回的,在函數返回時,如果我們不考慮返回值優化(NRV),那么也會產生一個臨時對象object_copy2,這個臨時對象會在函數返 回后一段時間內被釋放。比如某個函數中有如下代碼:

  • Type tt ,result ; //生成兩個棧對象
  • tt = fun(tt); //函數返回時,生成的是一個臨時對象object_copy2
  • 復制代碼

    上面的第二個語句的執行情況是這樣的,首先函數fun返回時生成一個臨時對象object_copy2 ,然后再調用賦值運算符執行

  • tt = object_copy2 ; //調用賦值運算符
  • 復制代碼

    看到了嗎?編譯器在我們毫無知覺的情況下,為我們生成了這么多臨時對象,而生成這些臨時對象的時間和空間的開銷可能是很大的,所以,你也許明白了,為什么對于“大”對象最好用const引用傳遞代替按值進行函數參數傳遞了。

      接下來,看看堆。堆,又叫自由存儲區,它是在程序執行的過程中動態分配的,所以它最大的特性就是動態性。在C++中,所有堆對象的創建和銷毀都要由程 序員負責,所以,如果處理不好,就會發生內存問題。如果分配了堆對象,卻忘記了釋放,就會產生內存泄漏;而如果已釋放了對象,卻沒有將相應的指針置為 NULL,該指針就是所謂的“懸掛指針”,再度使用此指針時,就會出現非法訪問,嚴重時就導致程序崩潰。

      那么,C++中是怎樣分配堆對象的?唯一的方法就是用new(當然,用類malloc指令也可獲得C式堆內存),只要使用new,就會在堆中分配一塊內存,并且返回指向該堆對象的指針。

      再來看看靜態存儲區。所有的靜態對象、全局對象都于靜態存儲區分配。關于全局對象,是在main()函數執行前就分配好了的。其實,在 main()函數中的顯示代碼執行之前,會調用一個由編譯器生成的_main()函數,而_main()函數會進行所有全局對象的的構造及初始化工作。而 在main()函數結束之前,會調用由編譯器生成的exit函數,來釋放所有的全局對象。比如下面的代碼:

  • void main(void)
  • {
  •  … …// 顯式代碼
  • }
  • 復制代碼

    實際上,被轉化成這樣:

  • void main(void)
  • {
  •  _main(); //隱式代碼,由編譯器產生,用以構造所有全局對象
  •  … … // 顯式代碼
  •  exit() ; // 隱式代碼,由編譯器產生,用以釋放所有全局對象
  • }
  • 復制代碼

    所 以,知道了這個之后,便可以由此引出一些技巧,如,假設我們要在main()函數執行之前做某些準備工作,那么我們可以將這些準備工作寫到一個自定義的全 局對象的構造函數中,這樣,在main()函數的顯式代碼執行之前,這個全局對象的構造函數會被調用,執行預期的動作,這樣就達到了我們的目的。剛才講的 是靜態存儲區中的全局對象,那么,局部靜態對象了?局部靜態對象通常也是在函數中定義的,就像棧對象一樣,只不過,其前面多了個static關鍵字。局部 靜態對象的生命期是從其所在函數第一次被調用,更確切地說,是當第一次執行到該靜態對象的聲明代碼時,產生該靜態局部對象,直到整個程序結束時,才銷毀該 對象。

      還有一種靜態對象,那就是它作為class的靜態成員。考慮這種情況時,就牽涉了一些較復雜的問題。

      第一個問題是class的靜態成員對象的生命期,class的靜態成員對象隨著第一個class object的產生而產生,在整個程序結束時消亡。也就是有這樣的情況存在,在程序中我們定義了一個class,該類中有一個靜態對象作為成員,但是在程 序執行過程中,如果我們沒有創建任何一個該class object,那么也就不會產生該class所包含的那個靜態對象。還有,如果創建了多個class object,那么所有這些object都共享那個靜態對象成員。

      第二個問題是,當出現下列情況時:

  • class Base
  • {
  •  public:
  •   static Type s_object ;
  • }
  • class Derived1 : public Base / / 公共繼承
  • {
  •  … …// other data
  • }
  • class Derived2 : public Base / / 公共繼承
  • {
  •  … …// other data
  • }
  • Base example ;
  • Derivde1 example1 ;
  • Derivde2 example2 ;
  • example.s_object = …… ;
  • example1.s_object = …… ;
  • example2.s_object = …… ;
  • 復制代碼

    請 注意上面標為黑體的三條語句,它們所訪問的s_object是同一個對象嗎?答案是肯定的,它們的確是指向同一個對象,這聽起來不像是真的,是嗎?但這是 事實,你可以自己寫段簡單的代碼驗證一下。我要做的是來解釋為什么會這樣?我們知道,當一個類比如Derived1,從另一個類比如Base繼承時,那 么,可以看作一個Derived1對象中含有一個Base型的對象,這就是一個subobject。一個Derived1對象的大致內存布局如下:
      
      讓我們想想,當我們將一個Derived1型的對象傳給一個接受非引用Base型參數的函數時會發生切割,那么是怎么切割的呢?相信現在你已經知道 了,那就是僅僅取出了Derived1型的對象中的subobject,而忽略了所有Derived1自定義的其它數據成員,然后將這個 subobject傳遞給函數(實際上,函數中使用的是這個subobject的拷貝)。

      所有繼承Base類的派生類的對象都含有一個Base型的subobject(這是能用Base型指針指向一個Derived1對象的關鍵所在,自然 也是多態的關鍵了),而所有的subobject和所有Base型的對象都共用同一個s_object對象,自然,從Base類派生的整個繼承體系中的類 的實例都會共用同一個s_object對象了。上面提到的example、example1、example2的對象布局如下圖所示:

    3.1.2 三種內存對象的比較

      棧對象的優勢是在適當的時候自動生成,又在適當的時候自動銷毀,不需要程序員操心;而且棧對象的創建速度一般較堆對象快,因為分配堆對象時,會調用 operator new操作,operator new會采用某種內存空間搜索算法,而該搜索過程可能是很費時間的,產生棧對象則沒有這么麻煩,它僅僅需要移動棧頂指針就可以了。但是要注意的是,通常棧 空間容量比較小,一般是1MB~2MB,所以體積比較大的對象不適合在棧中分配。特別要注意遞歸函數中最好不要使用棧對象,因為隨著遞歸調用深度的增加, 所需的棧空間也會線性增加,當所需棧空間不夠時,便會導致棧溢出,這樣就會產生運行時錯誤。

      堆對象,其產生時刻和銷毀時刻都要程序員精確定義,也就是說,程序員對堆對象的生命具有完全的控制權。我們常常需要這樣的對象,比如,我們需要創建一 個對象,能夠被多個函數所訪問,但是又不想使其成為全局的,那么這個時候創建一個堆對象無疑是良好的選擇,然后在各個函數之間傳遞這個堆對象的指針,便可 以實現對該對象的共享。另外,相比于棧空間,堆的容量要大得多。實際上,當物理內存不夠時,如果這時還需要生成新的堆對象,通常不會產生運行時錯誤,而是 系統會使用虛擬內存來擴展實際的物理內存。

    接下來看看static對象。

      首先是全局對象。全局對象為類間通信和函數間通信提供了一種最簡單的方式,雖然這種方式并不優雅。一般而言,在完全的面向對象語言中,是不存在全局對 象的,比如C#,因為全局對象意味著不安全和高耦合,在程序中過多地使用全局對象將大大降低程序的健壯性、穩定性、可維護性和可復用性。C++也完全可以 剔除全局對象,但是最終沒有,我想原因之一是為了兼容C。

      其次是類的靜態成員,上面已經提到,基類及其派生類的所有對象都共享這個靜態成員對象,所以當需要在這些class之間或這些class objects之間進行數據共享或通信時,這樣的靜態成員無疑是很好的選擇。

      接著是靜態局部對象,主要可用于保存該對象所在函數被屢次調用期間的中間狀態,其中一個最顯著的例子就是遞歸函數,我們都知道遞歸函數是自己調用自己 的函數,如果在遞歸函數中定義一個nonstatic局部對象,那么當遞歸次數相當大時,所產生的開銷也是巨大的。這是因為nonstatic局部對象是 棧對象,每遞歸調用一次,就會產生一個這樣的對象,每返回一次,就會釋放這個對象,而且,這樣的對象只局限于當前調用層,對于更深入的嵌套層和更淺露的外 層,都是不可見的。每個層都有自己的局部對象和參數。

      在遞歸函數設計中,可以使用static對象替代nonstatic局部對象(即棧對象),這不僅可以減少每次遞歸調用和返回時產生和釋放nonstatic對象的開銷,而且static對象還可以保存遞歸調用的中間狀態,并且可為各個調用層所訪問。

    3.1.3 使用棧對象的意外收獲

      前面已經介紹到,棧對象是在適當的時候創建,然后在適當的時候自動釋放的,也就是棧對象有自動管理功能。那么棧對象會在什么會自動釋放了?第一,在其 生命期結束的時候;第二,在其所在的函數發生異常的時候。你也許說,這些都很正常啊,沒什么大不了的。是的,沒什么大不了的。但是只要我們再深入一點點, 也許就有意外的收獲了。

      棧對象,自動釋放時,會調用它自己的析構函數。如果我們在棧對象中封裝資源,而且在棧對象的析構函數中執行釋放資源的動作,那么就會使資源泄漏的概率 大大降低,因為棧對象可以自動的釋放資源,即使在所在函數發生異常的時候。實際的過程是這樣的:函數拋出異常時,會發生所謂的 stack_unwinding(堆棧回滾),即堆棧會展開,由于是棧對象,自然存在于棧中,所以在堆棧回滾的過程中,棧對象的析構函數會被執行,從而釋 放其所封裝的資源。除非,除非在析構函數執行的過程中再次拋出異常――而這種可能性是很小的,所以用棧對象封裝資源是比較安全的。基于此認識,我們就可以 創建一個自己的句柄或代理來封裝資源了。智能指針(auto_ptr)中就使用了這種技術。在有這種需要的時候,我們就希望我們的資源封裝類只能在棧中創 建,也就是要限制在堆中創建該資源封裝類的實例。

    3.1.4 禁止產生堆對象

      上面已經提到,你決定禁止產生某種類型的堆對象,這時你可以自己創建一個資源封裝類,該類對象只能在棧中產生,這樣就能在異常的情況下自動釋放封裝的資源。

      那么怎樣禁止產生堆對象了?我們已經知道,產生堆對象的唯一方法是使用new操作,如果我們禁止使用new不就行了么。再進一步,new操作執行時會 調用operator new,而operator new是可以重載的。方法有了,就是使new operator 為private,為了對稱,最好將operator delete也重載為private。現在,你也許又有疑問了,難道創建棧對象不需要調用new嗎?是的,不需要,因為創建棧對象不需要搜索內存,而是直 接調整堆棧指針,將對象壓棧,而operator new的主要任務是搜索合適的堆內存,為堆對象分配空間,這在上面已經提到過了。好,讓我們看看下面的示例代碼:

  • #include <stdlib.h> //需要用到C式內存分配函數
  • class Resource ; //代表需要被封裝的資源類
  • class NoHashObject
  • {
  •  private:
  •   Resource* ptr ;//指向被封裝的資源
  •   ... ... //其它數據成員
  •   void* operator new(size_t size) //非嚴格實現,僅作示意之用
  •   {
  •    return malloc(size) ;
  •   }
  •   void operator delete(void* pp) //非嚴格實現,僅作示意之用
  •   {
  •    free(pp) ;
  •   }
  •  public:
  •   NoHashObject()
  •   {
  •    //此處可以獲得需要封裝的資源,并讓ptr指針指向該資源
  •    ptr = new Resource() ;
  •   }
  •   ~NoHashObject()
  •   {
  •    delete ptr ; //釋放封裝的資源
  •   }
  • };
  • 復制代碼

    NoHashObject現在就是一個禁止堆對象的類了,如果你寫下如下代碼:

  • NoHashObject* fp = new NoHashObject() ; //編譯期錯誤!
  • delete fp ;
  • 復制代碼

    上 面代碼會產生編譯期錯誤。好了,現在你已經知道了如何設計一個禁止堆對象的類了,你也許和我一樣有這樣的疑問,難道在類NoHashObject 的定義不能改變的情況下,就一定不能產生該類型的堆對象了嗎?不,還是有辦法的,我稱之為“暴力破解法”。C++是如此地強大,強大到你可以用它做你想做 的任何事情。這里主要用到的是技巧是指針類型的強制轉換。

  • void main(void)
  • {
  •  char* temp = new char[sizeof(NoHashObject)] ;
  •  //強制類型轉換,現在ptr是一個指向NoHashObject對象的指針
  •  NoHashObject* obj_ptr = (NoHashObject*)temp ;
  •  temp = NULL ; //防止通過temp指針修改NoHashObject對象
  •  //再一次強制類型轉換,讓rp指針指向堆中NoHashObject對象的ptr成員
  •  Resource* rp = (Resource*)obj_ptr ;
  •  //初始化obj_ptr指向的NoHashObject對象的ptr成員
  •  rp = new Resource() ;
  •  //現在可以通過使用obj_ptr指針使用堆中的NoHashObject對象成員了
  •  ... ...
  •  delete rp ;//釋放資源
  •  temp = (char*)obj_ptr ;
  •  obj_ptr = NULL ;//防止懸掛指針產生
  •  delete [] temp ;//釋放NoHashObject對象所占的堆空間。
  • }
  • 復制代碼

    上面的實現是麻煩的,而且這種實現方式幾乎不會在實踐中使用,但是我還是寫出來路,因為理解它,對于我們理解C++內存對象是有好處的。對于上面的這么多強制類型轉換,其最根本的是什么了?我們可以這樣理解:

      某塊內存中的數據是不變的,而類型就是我們戴上的眼鏡,當我們戴上一種眼鏡后,我們就會用對應的類型來解釋內存中的數據,這樣不同的解釋就得到了不同的信息。

      所謂強制類型轉換實際上就是換上另一副眼鏡后再來看同樣的那塊內存數據。

      另外要提醒的是,不同的編譯器對對象的成員數據的布局安排可能是不一樣的,比如,大多數編譯器將NoHashObject的ptr指針成員安排在對象空間的頭4個字節,這樣才會保證下面這條語句的轉換動作像我們預期的那樣執行:

  • Resource* rp = (Resource*)obj_ptr;
  • 復制代碼

    但是,并不一定所有的編譯器都是如此。

      既然我們可以禁止產生某種類型的堆對象,那么可以設計一個類,使之不能產生棧對象嗎?當然可以。

    3.1.5 禁止產生棧對象

      前面已經提到了,創建棧對象時會移動棧頂指針以“挪出”適當大小的空間,然后在這個空間上直接調用對應的構造函數以形成一個棧對象,而當函數返回時, 會調用其析構函數釋放這個對象,然后再調整棧頂指針收回那塊棧內存。在這個過程中是不需要operator new/delete操作的,所以將operator new/delete設置為private不能達到目的。當然從上面的敘述中,你也許已經想到了:將構造函數或析構函數設為私有的,這樣系統就不能調用構 造/析構函數了,當然就不能在棧中生成對象了。

      這樣的確可以,而且我也打算采用這種方案。但是在此之前,有一點需要考慮清楚,那就是,如果我們將構造函數設置為私有,那么我們也就不能用 new來直接產生堆對象了,因為new在為對象分配空間后也會調用它的構造函數啊。所以,我打算只將析構函數設置為private。再進一步,將析構函數 設為private除了會限制棧對象生成外,還有其它影響嗎?是的,這還會限制繼承。

      如果一個類不打算作為基類,通常采用的方案就是將其析構函數聲明為private。

      為了限制棧對象,卻不限制繼承,我們可以將析構函數聲明為protected,這樣就兩全其美了。如下代碼所示:

  • class NoStackObject
  • {
  •  protected:
  •   ~NoStackObject() { }
  •  public:
  •   void destroy()
  •   {
  •    delete this ;//調用保護析構函數
  •   }
  • };
  • 復制代碼

    接著,可以像這樣使用NoStackObject類:

  • NoStackObject* hash_ptr = new NoStackObject() ;
  • ... ... //對hash_ptr指向的對象進行操作
  • hash_ptr->destroy() ;
  • 復制代碼

    呵 呵,是不是覺得有點怪怪的,我們用new創建一個對象,卻不是用delete去刪除它,而是要用destroy方法。很顯然,用戶是不習慣這種怪異的使用 方式的。所以,我決定將構造函數也設為private或protected。這又回到了上面曾試圖避免的問題,即不用new,那么該用什么方式來生成一個 對象了?我們可以用間接的辦法完成,即讓這個類提供一個static成員函數專門用于產生該類型的堆對象。(設計模式中的singleton 模式就可以用這種方式實現。)讓我們來看看:

  • class NoStackObject
  • {
  •  protected:
  •   NoStackObject() { }
  •   ~NoStackObject() { }
  •  public:
  •   static NoStackObject* creatInstance()
  •   {
  •    return new NoStackObject() ;//調用保護的構造函數
  •   }
  •   void destroy()
  •   {
  •    delete this ;//調用保護的析構函數
  •   }
  • };
  • 復制代碼

    現在可以這樣使用NoStackObject類了:

  • NoStackObject* hash_ptr = NoStackObject::creatInstance() ;
  • ... ... //對hash_ptr指向的對象進行操作
  • hash_ptr->destroy() ;
  • hash_ptr = NULL ; //防止使用懸掛指針
  • 復制代碼

    現在感覺是不是好多了,生成對象和釋放對象的操作一致了。

    3.2 淺議C++ 中的垃圾回收方法

      許多 C 或者 C++ 程序員對垃圾回收嗤之以鼻,認為垃圾回收肯定比自己來管理動態內存要低效,而且在回收的時候一定會讓程序停頓在那里,而如果自己控制內存管理的話,分配和 釋放時間都是穩定的,不會導致程序停頓。最后,很多 C/C++ 程序員堅信在C/C++ 中無法實現垃圾回收機制。這些錯誤的觀點都是由于不了解垃圾回收的算法而臆想出來的。

      其實垃圾回收機制并不慢,甚至比動態內存分配更高效。因為我們可以只分配不釋放,那么分配內存的時候只需要從堆上一直的獲得新的內存,移動堆頂的指針 就夠了;而釋放的過程被省略了,自然也加快了速度。現代的垃圾回收算法已經發展了很多,增量收集算法已經可以讓垃圾回收過程分段進行,避免打斷程序的運行 了。而傳統的動態內存管理的算法同樣有在適當的時間收集內存碎片的工作要做,并不比垃圾回收更有優勢。

      而垃圾回收的算法的基礎通常基于掃描并標記當前可能被使用的所有內存塊,從已經被分配的所有內存中把未標記的內存回收來做的。C/C++ 中無法實現垃圾回收的觀點通常基于無法正確掃描出所有可能還會被使用的內存塊,但是,看似不可能的事情實際上實現起來卻并不復雜。首先,通過掃描內存的數 據,指向堆上動態分配出來內存的指針是很容易被識別出來的,如果有識別錯誤,也只能是把一些不是指針的數據當成指針,而不會把指針當成非指針數據。這樣, 回收垃圾的過程只會漏回收掉而不會錯誤的把不應該回收的內存清理。其次,如果回溯所有內存塊被引用的根,只可能存在于全局變量和當前的棧內,而全局變量 (包括函數內的靜態變量)都是集中存在于 bss 段或 data段中。

      垃圾回收的時候,只需要掃描 bss 段, data 段以及當前被使用著的棧空間,找到可能是動態內存指針的量,把引用到的內存遞歸掃描就可以得到當前正在使用的所有動態內存了。

      如果肯為你的工程實現一個不錯的垃圾回收器,提高內存管理的速度,甚至減少總的內存消耗都是可能的。如果有興趣的話,可以搜索一下網上已有的關于垃圾回收的論文和實現了的庫,開拓視野對一個程序員尤為重要。

    發表于 @ 2010年07月02日 09:27:00?|?評論(?0?)?|?舉報|?收藏

    總結

    以上是生活随笔為你收集整理的C语言运行时库详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    天天摸天天透天天添 | 亚洲国产成人av在线观看 | 国产偷抇久久精品a片69 | 亚洲国产日韩a在线播放 | 无码成人精品区在线观看 | 日本乱偷人妻中文字幕 | аⅴ资源天堂资源库在线 | 国产真人无遮挡作爱免费视频 | 高清无码午夜福利视频 | 在线播放亚洲第一字幕 | 国产偷自视频区视频 | 中文无码成人免费视频在线观看 | 亚洲区欧美区综合区自拍区 | 国产精品久久久久9999小说 | 国产成人精品一区二区在线小狼 | 日韩少妇白浆无码系列 | 无码乱肉视频免费大全合集 | 鲁大师影院在线观看 | 中文字幕av伊人av无码av | 国产欧美精品一区二区三区 | 伊人色综合久久天天小片 | 日本熟妇浓毛 | 爱做久久久久久 | 精品国产福利一区二区 | 扒开双腿吃奶呻吟做受视频 | 精品aⅴ一区二区三区 | 亚洲综合另类小说色区 | 日本免费一区二区三区最新 | 免费网站看v片在线18禁无码 | 99久久精品日本一区二区免费 | 中文字幕乱妇无码av在线 | 亚洲人成网站在线播放942 | 国模大胆一区二区三区 | 131美女爱做视频 | 人人爽人人澡人人高潮 | 中文字幕日韩精品一区二区三区 | 久久久久久久久蜜桃 | 精品国偷自产在线视频 | 性生交大片免费看女人按摩摩 | 男女下面进入的视频免费午夜 | 性欧美牲交xxxxx视频 | 国产三级精品三级男人的天堂 | 欧洲美熟女乱又伦 | 欧美一区二区三区 | 国产黄在线观看免费观看不卡 | 国产偷自视频区视频 | 狠狠色欧美亚洲狠狠色www | 国产精品久久久av久久久 | 中文字幕无码日韩欧毛 | 欧美一区二区三区视频在线观看 | 国产综合在线观看 | 男女超爽视频免费播放 | 丰满妇女强制高潮18xxxx | 自拍偷自拍亚洲精品被多人伦好爽 | 久久久国产精品无码免费专区 | 成人性做爰aaa片免费看不忠 | 日本熟妇乱子伦xxxx | 爆乳一区二区三区无码 | 国精产品一品二品国精品69xx | 成熟人妻av无码专区 | 国产成人av免费观看 | 国产av人人夜夜澡人人爽麻豆 | 一本色道久久综合亚洲精品不卡 | 久久综合香蕉国产蜜臀av | 麻豆果冻传媒2021精品传媒一区下载 | 精品国产麻豆免费人成网站 | 特级做a爰片毛片免费69 | 人妻少妇精品无码专区二区 | 国产精品怡红院永久免费 | 熟妇人妻激情偷爽文 | 性生交大片免费看l | 国产成人午夜福利在线播放 | 亚洲爆乳大丰满无码专区 | 亚洲色无码一区二区三区 | 国产麻豆精品精东影业av网站 | 欧美丰满老熟妇xxxxx性 | 天下第一社区视频www日本 | 亚洲伊人久久精品影院 | 东京热男人av天堂 | 奇米影视7777久久精品人人爽 | 亚洲一区二区三区含羞草 | 精品国产成人一区二区三区 | 国产午夜无码视频在线观看 | 久热国产vs视频在线观看 | 日韩精品无码一本二本三本色 | 丰腴饱满的极品熟妇 | 99国产欧美久久久精品 | 人妻插b视频一区二区三区 | 日本一本二本三区免费 | √天堂中文官网8在线 | 真人与拘做受免费视频一 | 日本大乳高潮视频在线观看 | 狠狠亚洲超碰狼人久久 | 荡女精品导航 | 人妻互换免费中文字幕 | www国产精品内射老师 | 日本饥渴人妻欲求不满 | 亚洲乱码国产乱码精品精 | 天天综合网天天综合色 | 国产深夜福利视频在线 | 男人和女人高潮免费网站 | 奇米影视888欧美在线观看 | 中文字幕日韩精品一区二区三区 | 无码人妻丰满熟妇区毛片18 | 亚洲а∨天堂久久精品2021 | 人妻尝试又大又粗久久 | 亚洲人成无码网www | 一个人看的www免费视频在线观看 | 中文字幕av无码一区二区三区电影 | 亚洲熟妇色xxxxx欧美老妇 | 98国产精品综合一区二区三区 | 国产美女极度色诱视频www | 久久国语露脸国产精品电影 | 无遮挡啪啪摇乳动态图 | 久久综合色之久久综合 | 人人爽人人澡人人人妻 | 成人亚洲精品久久久久软件 | 黑人大群体交免费视频 | 国模大胆一区二区三区 | 久久久久亚洲精品男人的天堂 | 又大又硬又黄的免费视频 | 黑人粗大猛烈进出高潮视频 | 国产亚洲精品久久久闺蜜 | 十八禁真人啪啪免费网站 | 午夜免费福利小电影 | 国产精品永久免费视频 | 国产97人人超碰caoprom | 鲁鲁鲁爽爽爽在线视频观看 | 亚洲欧洲中文日韩av乱码 | 国产真实伦对白全集 | av无码久久久久不卡免费网站 | 色婷婷综合中文久久一本 | 国产精品亚洲专区无码不卡 | 97久久精品无码一区二区 | 亚洲国产精品久久久久久 | 日本精品久久久久中文字幕 | 无码人妻丰满熟妇区五十路百度 | 亚洲中文字幕在线无码一区二区 | 亚洲成av人影院在线观看 | 又大又紧又粉嫩18p少妇 | 久久精品成人欧美大片 | 欧美精品国产综合久久 | 在线观看国产午夜福利片 | 国产农村妇女高潮大叫 | 久久国产精品萌白酱免费 | 亚拍精品一区二区三区探花 | 无码国内精品人妻少妇 | 国产亚洲精品久久久闺蜜 | 最新版天堂资源中文官网 | 国产国产精品人在线视 | 国产亚洲美女精品久久久2020 | 色一情一乱一伦 | 国产精品永久免费视频 | 捆绑白丝粉色jk震动捧喷白浆 | 精品国产麻豆免费人成网站 | 搡女人真爽免费视频大全 | 97久久国产亚洲精品超碰热 | 国模大胆一区二区三区 | 青青草原综合久久大伊人精品 | a片免费视频在线观看 | 狂野欧美性猛交免费视频 | 欧美激情内射喷水高潮 | 人人爽人人澡人人高潮 | 国产精品久久久午夜夜伦鲁鲁 | 久久天天躁狠狠躁夜夜免费观看 | 欧洲熟妇精品视频 | 国产成人无码av片在线观看不卡 | 男人扒开女人内裤强吻桶进去 | av无码久久久久不卡免费网站 | 欧美精品无码一区二区三区 | 久久综合香蕉国产蜜臀av | 欧洲熟妇色 欧美 | 国产高清不卡无码视频 | 国产亚洲视频中文字幕97精品 | 无码国内精品人妻少妇 | 国产精品怡红院永久免费 | 亚洲区欧美区综合区自拍区 | 久久久久免费精品国产 | 亚洲精品一区二区三区在线 | 国产性生交xxxxx无码 | 中文字幕无码视频专区 | 一二三四在线观看免费视频 | 日韩av无码中文无码电影 | 国产xxx69麻豆国语对白 | 欧美野外疯狂做受xxxx高潮 | 久久久中文字幕日本无吗 | 久久人人爽人人爽人人片ⅴ | 亚洲成a人一区二区三区 | 精品国产成人一区二区三区 | 国产精品丝袜黑色高跟鞋 | 欧美日韩人成综合在线播放 | 久久国产自偷自偷免费一区调 | 国产人妻人伦精品1国产丝袜 | 欧美35页视频在线观看 | 丰满人妻一区二区三区免费视频 | 蜜臀av无码人妻精品 | 青春草在线视频免费观看 | 又大又硬又爽免费视频 | 亚洲人成人无码网www国产 | 国产激情无码一区二区 | 亚洲va中文字幕无码久久不卡 | 暴力强奷在线播放无码 | 中文精品久久久久人妻不卡 | 国产深夜福利视频在线 | 免费视频欧美无人区码 | 熟妇人妻无码xxx视频 | 少妇高潮一区二区三区99 | 少妇激情av一区二区 | 中国大陆精品视频xxxx | 欧美色就是色 | 亚洲七七久久桃花影院 | 国内精品人妻无码久久久影院 | 国产激情无码一区二区app | 国产亚洲视频中文字幕97精品 | 少妇高潮喷潮久久久影院 | 国精产品一品二品国精品69xx | 99国产欧美久久久精品 | 日本一区二区三区免费播放 | 老司机亚洲精品影院无码 | 又粗又大又硬毛片免费看 | 一本久道高清无码视频 | 日韩精品一区二区av在线 | 久久国内精品自在自线 | 最新版天堂资源中文官网 | 精品亚洲成av人在线观看 | 99久久精品午夜一区二区 | 男女作爱免费网站 | 国产一区二区三区四区五区加勒比 | 一本大道久久东京热无码av | 国产又粗又硬又大爽黄老大爷视 | 亚洲午夜无码久久 | 宝宝好涨水快流出来免费视频 | 午夜无码区在线观看 | 免费国产成人高清在线观看网站 | 人妻无码αv中文字幕久久琪琪布 | 亚洲欧洲中文日韩av乱码 | 国产香蕉尹人视频在线 | 小泽玛莉亚一区二区视频在线 | 亚洲欧美精品aaaaaa片 | 强奷人妻日本中文字幕 | 亚洲色大成网站www国产 | 亚拍精品一区二区三区探花 | 国产一区二区三区四区五区加勒比 | 亚洲精品午夜无码电影网 | 亚洲国产成人av在线观看 | 男人扒开女人内裤强吻桶进去 | 成人综合网亚洲伊人 | 亚洲阿v天堂在线 | 午夜精品一区二区三区在线观看 | 亚洲成a人一区二区三区 | av人摸人人人澡人人超碰下载 | 亚洲小说春色综合另类 | 蜜臀aⅴ国产精品久久久国产老师 | 亚洲精品中文字幕乱码 | 国产精品嫩草久久久久 | 成人精品一区二区三区中文字幕 | 国产精品永久免费视频 | 欧美日韩精品 | 亚洲啪av永久无码精品放毛片 | 老熟妇乱子伦牲交视频 | 中文字幕无码热在线视频 | 强开小婷嫩苞又嫩又紧视频 | 一本大道久久东京热无码av | 伊人久久大香线蕉av一区二区 | 亚洲日韩乱码中文无码蜜桃臀网站 | 美女扒开屁股让男人桶 | 人人妻人人藻人人爽欧美一区 | 永久黄网站色视频免费直播 | 无码乱肉视频免费大全合集 | 久久亚洲国产成人精品性色 | 亚洲国产av精品一区二区蜜芽 | 国产精品第一区揄拍无码 | 亚洲午夜福利在线观看 | 波多野结衣av一区二区全免费观看 | 亚洲欧美日韩成人高清在线一区 | 人人澡人人妻人人爽人人蜜桃 | 国产亚洲人成a在线v网站 | 人人超人人超碰超国产 | 无码毛片视频一区二区本码 | 国产精品久久福利网站 | 搡女人真爽免费视频大全 | 亚无码乱人伦一区二区 | 国产精品久久精品三级 | 大肉大捧一进一出视频出来呀 | 亚洲精品一区二区三区在线观看 | 人妻少妇被猛烈进入中文字幕 | 亚洲日本一区二区三区在线 | 久久国产36精品色熟妇 | 日韩av无码一区二区三区 | 无码人妻久久一区二区三区不卡 | 成人三级无码视频在线观看 | 久久综合九色综合欧美狠狠 | 免费男性肉肉影院 | 亚洲精品成a人在线观看 | 国产女主播喷水视频在线观看 | 精品国产aⅴ无码一区二区 | 国产网红无码精品视频 | 无遮无挡爽爽免费视频 | 久精品国产欧美亚洲色aⅴ大片 | 性生交大片免费看女人按摩摩 | 亚洲伊人久久精品影院 | 亚洲中文字幕在线无码一区二区 | 久久久久久国产精品无码下载 | 少妇人妻av毛片在线看 | 无码人妻久久一区二区三区不卡 | 四虎影视成人永久免费观看视频 | 国产精品亚洲专区无码不卡 | 亚洲另类伦春色综合小说 | www国产精品内射老师 | 正在播放老肥熟妇露脸 | 人妻天天爽夜夜爽一区二区 | 亚洲国产一区二区三区在线观看 | 国产午夜亚洲精品不卡下载 | 麻豆成人精品国产免费 | 高潮毛片无遮挡高清免费 | 成人试看120秒体验区 | 对白脏话肉麻粗话av | 国产av一区二区三区最新精品 | 国产97人人超碰caoprom | 99久久人妻精品免费二区 | 免费国产成人高清在线观看网站 | 熟女俱乐部五十路六十路av | 牲交欧美兽交欧美 | 亚洲爆乳大丰满无码专区 | 蜜桃视频韩日免费播放 | 色 综合 欧美 亚洲 国产 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 国产精品多人p群无码 | 久久久久se色偷偷亚洲精品av | 国产一区二区不卡老阿姨 | 51国偷自产一区二区三区 | 熟妇女人妻丰满少妇中文字幕 | yw尤物av无码国产在线观看 | 亚洲 高清 成人 动漫 | 国产热a欧美热a在线视频 | 夜精品a片一区二区三区无码白浆 | 玩弄人妻少妇500系列视频 | 国产精品久久国产精品99 | 女人被爽到呻吟gif动态图视看 | 牛和人交xxxx欧美 | 成在人线av无码免费 | 国产偷国产偷精品高清尤物 | 动漫av一区二区在线观看 | 乱码午夜-极国产极内射 | 精品无码国产一区二区三区av | 久久久久久a亚洲欧洲av冫 | 色窝窝无码一区二区三区色欲 | 中文字幕人妻无码一区二区三区 | 97夜夜澡人人爽人人喊中国片 | 久久精品国产一区二区三区 | 欧美刺激性大交 | 初尝人妻少妇中文字幕 | 婷婷丁香六月激情综合啪 | 国内精品久久毛片一区二区 | 无码人妻丰满熟妇区毛片18 | 久久99精品国产麻豆蜜芽 | 亚洲成色在线综合网站 | 无码人妻丰满熟妇区毛片18 | 免费国产成人高清在线观看网站 | 国产精品美女久久久网av | 日韩人妻无码一区二区三区久久99 | 一本精品99久久精品77 | 99久久人妻精品免费一区 | 亚洲成色在线综合网站 | √天堂资源地址中文在线 | 久久久亚洲欧洲日产国码αv | 色综合久久88色综合天天 | 亚洲一区二区三区 | 日产精品99久久久久久 | 国产乱人伦av在线无码 | 日韩无套无码精品 | 精品国产一区av天美传媒 | 国产片av国语在线观看 | 国产亚洲日韩欧美另类第八页 | 理论片87福利理论电影 | 一本精品99久久精品77 | 亚洲一区二区三区 | 日欧一片内射va在线影院 | 大地资源中文第3页 | 欧美精品国产综合久久 | 精品成在人线av无码免费看 | 丰满少妇女裸体bbw | 无码任你躁久久久久久久 | 亚洲gv猛男gv无码男同 | 一本无码人妻在中文字幕免费 | 久久久精品欧美一区二区免费 | 欧美丰满熟妇xxxx | 99精品视频在线观看免费 | 日韩欧美群交p片內射中文 | 伦伦影院午夜理论片 | 麻豆国产人妻欲求不满谁演的 | 真人与拘做受免费视频一 | 日本一区二区三区免费播放 | 久热国产vs视频在线观看 | 日本护士毛茸茸高潮 | 婷婷丁香六月激情综合啪 | 97资源共享在线视频 | 亚洲成a人片在线观看无码 | 欧美人与牲动交xxxx | 亚洲综合色区中文字幕 | 亚洲国产精品无码一区二区三区 | 在线视频网站www色 | 亚洲熟妇色xxxxx欧美老妇 | 亚洲日韩av一区二区三区四区 | 亚洲精品一区二区三区在线 | 久久久久se色偷偷亚洲精品av | 色综合久久久无码中文字幕 | 丰腴饱满的极品熟妇 | 亚洲欧洲中文日韩av乱码 | 丰满诱人的人妻3 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 亚洲色在线无码国产精品不卡 | 亚洲精品久久久久avwww潮水 | 少妇高潮喷潮久久久影院 | 欧美亚洲国产一区二区三区 | 夜夜躁日日躁狠狠久久av | 国产亲子乱弄免费视频 | 免费观看激色视频网站 | 亚洲乱码日产精品bd | 亚洲精品国产a久久久久久 | 国产乱人无码伦av在线a | 欧美放荡的少妇 | 欧美人与动性行为视频 | 欧美精品无码一区二区三区 | 国产极品视觉盛宴 | 性欧美疯狂xxxxbbbb | 色婷婷欧美在线播放内射 | 成人无码视频在线观看网站 | 国产一精品一av一免费 | 国产精品美女久久久网av | 亚洲精品午夜国产va久久成人 | 久久久婷婷五月亚洲97号色 | 国产精品久久久久久久影院 | 2020久久超碰国产精品最新 | 女人被男人躁得好爽免费视频 | 亚洲va中文字幕无码久久不卡 | 国内少妇偷人精品视频免费 | 男人的天堂2018无码 | 一本色道婷婷久久欧美 | 成人精品一区二区三区中文字幕 | 国产xxx69麻豆国语对白 | 午夜福利一区二区三区在线观看 | 亚洲色偷偷男人的天堂 | 欧美熟妇另类久久久久久多毛 | 国产三级精品三级男人的天堂 | 日韩人妻系列无码专区 | 久在线观看福利视频 | 亚洲一区二区三区香蕉 | 亚洲码国产精品高潮在线 | 国产精品亚洲专区无码不卡 | 综合人妻久久一区二区精品 | 精品人妻人人做人人爽 | 欧美阿v高清资源不卡在线播放 | 97精品人妻一区二区三区香蕉 | 高潮喷水的毛片 | 99久久精品日本一区二区免费 | 丰满人妻一区二区三区免费视频 | 亚洲国产综合无码一区 | 乱码午夜-极国产极内射 | 国产特级毛片aaaaaa高潮流水 | 日本熟妇大屁股人妻 | 男女性色大片免费网站 | 中文字幕乱码人妻无码久久 | 久久国产精品偷任你爽任你 | 六月丁香婷婷色狠狠久久 | 亚洲 激情 小说 另类 欧美 | 麻豆国产人妻欲求不满谁演的 | 无遮无挡爽爽免费视频 | 成人精品一区二区三区中文字幕 | 国产深夜福利视频在线 | 亚无码乱人伦一区二区 | 色一情一乱一伦一视频免费看 | 亚洲の无码国产の无码步美 | 久久99精品久久久久婷婷 | 中文字幕人妻无码一夲道 | 18无码粉嫩小泬无套在线观看 | 精品熟女少妇av免费观看 | 熟妇人妻中文av无码 | 人人妻人人澡人人爽人人精品浪潮 | 天天av天天av天天透 | 中文字幕人妻无码一区二区三区 | 中文字幕乱码人妻二区三区 | 丁香花在线影院观看在线播放 | 中文字幕无码热在线视频 | 18无码粉嫩小泬无套在线观看 | 熟妇女人妻丰满少妇中文字幕 | 亚洲а∨天堂久久精品2021 | 亚洲色www成人永久网址 | 国产成人精品久久亚洲高清不卡 | 国内揄拍国内精品少妇国语 | 国产av人人夜夜澡人人爽麻豆 | 国产97在线 | 亚洲 | 国产精品亚洲五月天高清 | 67194成是人免费无码 | 国产成人精品久久亚洲高清不卡 | 亚洲人交乣女bbw | 国产综合久久久久鬼色 | 国产精品久久久一区二区三区 | 精品亚洲韩国一区二区三区 | 色婷婷香蕉在线一区二区 | 亚洲无人区午夜福利码高清完整版 | 台湾无码一区二区 | 成人免费视频一区二区 | 樱花草在线播放免费中文 | 天海翼激烈高潮到腰振不止 | 99国产欧美久久久精品 | 内射爽无广熟女亚洲 | 亚洲精品午夜无码电影网 | 色欲综合久久中文字幕网 | 无码人妻丰满熟妇区五十路百度 | 精品无码av一区二区三区 | 亚洲人亚洲人成电影网站色 | 欧美日韩亚洲国产精品 | 好爽又高潮了毛片免费下载 | 午夜精品久久久久久久久 | 久久久久免费看成人影片 | 色五月丁香五月综合五月 | 国产成人精品必看 | 中文精品无码中文字幕无码专区 | 亚洲欧洲日本综合aⅴ在线 | 国产成人精品优优av | 国产精品久久久久7777 | 久久午夜无码鲁丝片 | 强伦人妻一区二区三区视频18 | 日本精品久久久久中文字幕 | 大肉大捧一进一出好爽视频 | 巨爆乳无码视频在线观看 | 奇米影视7777久久精品人人爽 | 亚洲国精产品一二二线 | 色婷婷综合激情综在线播放 | 日韩欧美中文字幕在线三区 | 亚洲第一无码av无码专区 | 欧美激情内射喷水高潮 | 人妻aⅴ无码一区二区三区 | av香港经典三级级 在线 | 乱码午夜-极国产极内射 | 亚洲色大成网站www | 乱码午夜-极国产极内射 | 初尝人妻少妇中文字幕 | 国产在线一区二区三区四区五区 | 少妇愉情理伦片bd | 国产精品香蕉在线观看 | 日日麻批免费40分钟无码 | 亚洲乱码日产精品bd | 无码av岛国片在线播放 | 樱花草在线播放免费中文 | 中国女人内谢69xxxx | 成人毛片一区二区 | 少妇性l交大片欧洲热妇乱xxx | 亚洲一区二区三区 | 欧美日韩综合一区二区三区 | 国产97人人超碰caoprom | 国产精品久久久午夜夜伦鲁鲁 | 色综合久久久久综合一本到桃花网 | 在线精品亚洲一区二区 | 国产成人综合色在线观看网站 | 久久熟妇人妻午夜寂寞影院 | 自拍偷自拍亚洲精品10p | 97人妻精品一区二区三区 | 国产精品美女久久久 | 在线天堂新版最新版在线8 | 成人三级无码视频在线观看 | 国产精品香蕉在线观看 | 亚洲欧洲无卡二区视頻 | 久久亚洲日韩精品一区二区三区 | 国産精品久久久久久久 | 久久久久亚洲精品男人的天堂 | 亚洲成av人在线观看网址 | 欧美成人家庭影院 | 超碰97人人做人人爱少妇 | 无码吃奶揉捏奶头高潮视频 | 天天拍夜夜添久久精品 | 天下第一社区视频www日本 | 夜精品a片一区二区三区无码白浆 | 在线观看免费人成视频 | 国产sm调教视频在线观看 | 久久天天躁狠狠躁夜夜免费观看 | 日本乱偷人妻中文字幕 | 黑人玩弄人妻中文在线 | 亚洲成色在线综合网站 | 国产深夜福利视频在线 | 久久99精品久久久久久动态图 | 亚洲七七久久桃花影院 | 午夜丰满少妇性开放视频 | 日韩成人一区二区三区在线观看 | 色综合久久中文娱乐网 | 人人澡人人透人人爽 | 中文字幕 亚洲精品 第1页 | 无码免费一区二区三区 | 精品国产精品久久一区免费式 | 无码人妻丰满熟妇区五十路百度 | 亚洲aⅴ无码成人网站国产app | 中文字幕av无码一区二区三区电影 | 久久久久久a亚洲欧洲av冫 | 无码国产乱人伦偷精品视频 | 窝窝午夜理论片影院 | 国内少妇偷人精品视频 | 亚洲一区二区三区偷拍女厕 | 一二三四在线观看免费视频 | 俄罗斯老熟妇色xxxx | 老头边吃奶边弄进去呻吟 | 国产精品99爱免费视频 | 中国女人内谢69xxxx | 99久久精品日本一区二区免费 | 丰满少妇弄高潮了www | 伦伦影院午夜理论片 | 四虎国产精品免费久久 | 麻豆人妻少妇精品无码专区 | 鲁鲁鲁爽爽爽在线视频观看 | 免费人成在线视频无码 | 国产成人精品久久亚洲高清不卡 | 伊人久久大香线蕉av一区二区 | aⅴ亚洲 日韩 色 图网站 播放 | 午夜嘿嘿嘿影院 | 国产精品亚洲专区无码不卡 | 日本精品高清一区二区 | 久久 国产 尿 小便 嘘嘘 | 国产免费久久久久久无码 | 乱人伦人妻中文字幕无码久久网 | 久久久av男人的天堂 | 99riav国产精品视频 | 精品偷自拍另类在线观看 | 色综合久久久久综合一本到桃花网 | 精品成在人线av无码免费看 | 一本久道高清无码视频 | 亚洲va中文字幕无码久久不卡 | 日本欧美一区二区三区乱码 | av香港经典三级级 在线 | 131美女爱做视频 | 亚洲精品久久久久中文第一幕 | 国产美女极度色诱视频www | 国产精品久久国产三级国 | 永久免费精品精品永久-夜色 | 给我免费的视频在线观看 | 亚洲一区二区三区国产精华液 | 丰满岳乱妇在线观看中字无码 | 兔费看少妇性l交大片免费 | 人妻天天爽夜夜爽一区二区 | 又大又紧又粉嫩18p少妇 | 99久久久国产精品无码免费 | 国产乡下妇女做爰 | 精品久久久久香蕉网 | 国产精品igao视频网 | 国产另类ts人妖一区二区 | 成年美女黄网站色大免费视频 | 国产亚洲精品久久久久久久久动漫 | 青青草原综合久久大伊人精品 | 国产成人综合色在线观看网站 | 人妻少妇精品久久 | 亚洲色成人中文字幕网站 | 亚洲色欲久久久综合网东京热 | 日本精品人妻无码免费大全 | 人人妻人人澡人人爽欧美一区九九 | 色一情一乱一伦一区二区三欧美 | 一本久道高清无码视频 | 全黄性性激高免费视频 | 亚洲伊人久久精品影院 | 亚洲中文字幕无码中字 | 波多野结衣一区二区三区av免费 | 国产精品办公室沙发 | 国产偷自视频区视频 | 精品国产乱码久久久久乱码 | 无码国模国产在线观看 | 亚洲一区二区三区无码久久 | 欧美成人免费全部网站 | 久久久久se色偷偷亚洲精品av | 久久国产自偷自偷免费一区调 | 精品一二三区久久aaa片 | 377p欧洲日本亚洲大胆 | 国产激情艳情在线看视频 | 欧美兽交xxxx×视频 | 荡女精品导航 | 亚洲综合久久一区二区 | 精品人人妻人人澡人人爽人人 | 午夜无码区在线观看 | 国产精品国产三级国产专播 | 人人妻人人澡人人爽欧美一区 | 日日天日日夜日日摸 | 亚洲午夜无码久久 | 欧美人与物videos另类 | 一区二区三区乱码在线 | 欧洲 | 欧洲熟妇色 欧美 | 国内老熟妇对白xxxxhd | 大胆欧美熟妇xx | 精品亚洲成av人在线观看 | 国产精品亚洲综合色区韩国 | 国产九九九九九九九a片 | 久久99热只有频精品8 | 午夜精品久久久内射近拍高清 | 夜夜高潮次次欢爽av女 | 久久综合九色综合欧美狠狠 | 中文字幕人妻无码一区二区三区 | 久久精品国产一区二区三区肥胖 | 青青青手机频在线观看 | 国产人妻精品一区二区三区不卡 | 亚洲人成网站在线播放942 | 中文字幕 亚洲精品 第1页 | 无码国产激情在线观看 | 日本一区二区更新不卡 | 久久久久99精品成人片 | 久久国产精品偷任你爽任你 | 精品久久久无码中文字幕 | 精品无码国产一区二区三区av | 樱花草在线社区www | 国产美女精品一区二区三区 | 在线а√天堂中文官网 | 一个人免费观看的www视频 | 国产99久久精品一区二区 | 天天综合网天天综合色 | 国产超碰人人爽人人做人人添 | 伊人色综合久久天天小片 | аⅴ资源天堂资源库在线 | 国产成人综合在线女婷五月99播放 | 亚洲男女内射在线播放 | 午夜成人1000部免费视频 | 乱码午夜-极国产极内射 | 成人欧美一区二区三区黑人 | 黑人巨大精品欧美一区二区 | 国产偷国产偷精品高清尤物 | 国产成人综合色在线观看网站 | 国产成人综合在线女婷五月99播放 | 国产亚洲精品久久久久久久 | 亚洲无人区一区二区三区 | 一本久道高清无码视频 | 亚洲色欲色欲欲www在线 | 国产亚洲精品久久久闺蜜 | 成人免费视频视频在线观看 免费 | 亚洲精品久久久久avwww潮水 | 国产av无码专区亚洲awww | 日本一区二区三区免费播放 | 亚洲精品国产第一综合99久久 | 国产成人无码av片在线观看不卡 | 少妇无码一区二区二三区 | 成人欧美一区二区三区黑人免费 | 欧美丰满少妇xxxx性 | 日本熟妇乱子伦xxxx | 国产成人精品优优av | 亚洲熟熟妇xxxx | 少女韩国电视剧在线观看完整 | 免费国产黄网站在线观看 | 免费无码的av片在线观看 | 成在人线av无码免观看麻豆 | 天海翼激烈高潮到腰振不止 | 宝宝好涨水快流出来免费视频 | 国产精品久久国产三级国 | 亚洲国产精品久久久天堂 | 欧洲熟妇精品视频 | 国产午夜福利亚洲第一 | 秋霞特色aa大片 | 亚洲爆乳精品无码一区二区三区 | 欧美zoozzooz性欧美 | 国产麻豆精品精东影业av网站 | 亚洲啪av永久无码精品放毛片 | 1000部啪啪未满十八勿入下载 | 亚洲欧美精品aaaaaa片 | 99久久人妻精品免费二区 | 无码福利日韩神码福利片 | 亚洲国产精品毛片av不卡在线 | 日欧一片内射va在线影院 | 亚洲va中文字幕无码久久不卡 | 狂野欧美性猛xxxx乱大交 | 无码乱肉视频免费大全合集 | 丰满人妻精品国产99aⅴ | 六十路熟妇乱子伦 | 玩弄少妇高潮ⅹxxxyw | 国产国语老龄妇女a片 | 日本熟妇人妻xxxxx人hd | 88国产精品欧美一区二区三区 | 亚洲一区二区三区在线观看网站 | 蜜桃臀无码内射一区二区三区 | www国产亚洲精品久久久日本 | 无码吃奶揉捏奶头高潮视频 | 综合网日日天干夜夜久久 | 日韩精品无码一本二本三本色 | 性啪啪chinese东北女人 | 国产尤物精品视频 | 精品久久久久久人妻无码中文字幕 | 97夜夜澡人人双人人人喊 | 亚洲无人区午夜福利码高清完整版 | 亚洲色偷偷男人的天堂 | 日韩欧美群交p片內射中文 | 亚洲日韩av片在线观看 | 女人色极品影院 | 精品国产一区二区三区av 性色 | 成人无码精品一区二区三区 | 国产真实夫妇视频 | 国产免费久久久久久无码 | 成人三级无码视频在线观看 | 国产亚洲精品久久久久久久久动漫 | 国内精品一区二区三区不卡 | 中文字幕人妻无码一夲道 | 日韩人妻无码一区二区三区久久99 | 熟女少妇人妻中文字幕 | 国产特级毛片aaaaaa高潮流水 | 国内精品久久久久久中文字幕 | 人妻aⅴ无码一区二区三区 | 熟妇人妻无码xxx视频 | 亚洲s色大片在线观看 | 99久久久国产精品无码免费 | 国产人妻精品一区二区三区不卡 | 波多野结衣高清一区二区三区 | 亚洲国产欧美国产综合一区 | 中文无码精品a∨在线观看不卡 | 2020久久超碰国产精品最新 | 性欧美熟妇videofreesex | 亚洲综合无码久久精品综合 | 无码人妻少妇伦在线电影 | 亚洲人成影院在线无码按摩店 | 亚洲欧洲日本综合aⅴ在线 | 午夜丰满少妇性开放视频 | 亚洲精品一区国产 | 亚洲国产高清在线观看视频 | 日本丰满熟妇videos | 狠狠色丁香久久婷婷综合五月 | 九九在线中文字幕无码 | 国产无遮挡吃胸膜奶免费看 | 又大又硬又爽免费视频 | 久久99精品国产麻豆 | 国产激情无码一区二区 | 午夜丰满少妇性开放视频 | 日韩人妻系列无码专区 | 东京无码熟妇人妻av在线网址 | 久久天天躁狠狠躁夜夜免费观看 | 国内精品久久毛片一区二区 | 国产超级va在线观看视频 | 丰满人妻被黑人猛烈进入 | 水蜜桃亚洲一二三四在线 | 99久久无码一区人妻 | 人人妻人人澡人人爽人人精品浪潮 | 国产一区二区三区四区五区加勒比 | 人人澡人人妻人人爽人人蜜桃 | 亚洲成a人一区二区三区 | 99在线 | 亚洲 | 欧美成人高清在线播放 | 亚洲а∨天堂久久精品2021 | 玩弄中年熟妇正在播放 | 亚洲人成影院在线无码按摩店 | 日产精品高潮呻吟av久久 | 欧美日韩视频无码一区二区三 | 久久精品国产99精品亚洲 | 国产精品丝袜黑色高跟鞋 | 欧美变态另类xxxx | 日日摸天天摸爽爽狠狠97 | 少女韩国电视剧在线观看完整 | 精品久久久久久亚洲精品 | 亚洲欧美日韩成人高清在线一区 | 国产精品久久久一区二区三区 | 人人妻在人人 | 人人爽人人澡人人高潮 | 激情亚洲一区国产精品 | 无码人妻精品一区二区三区下载 | 日韩精品无码一区二区中文字幕 | 88国产精品欧美一区二区三区 | 久久婷婷五月综合色国产香蕉 | 国产一精品一av一免费 | 乱码av麻豆丝袜熟女系列 | 国产亚av手机在线观看 | 四虎影视成人永久免费观看视频 | 亚洲爆乳无码专区 | 欧美 日韩 亚洲 在线 | 樱花草在线播放免费中文 | 青青久在线视频免费观看 | 97人妻精品一区二区三区 | 成在人线av无码免观看麻豆 | 久久国产精品偷任你爽任你 | 国产欧美精品一区二区三区 | 国产精品久久久久久亚洲毛片 | 黑人粗大猛烈进出高潮视频 | 亚洲性无码av中文字幕 | a片在线免费观看 | 久久久久久久人妻无码中文字幕爆 | 永久免费精品精品永久-夜色 | 日本一卡二卡不卡视频查询 | 国产另类ts人妖一区二区 | 97精品人妻一区二区三区香蕉 | 特黄特色大片免费播放器图片 | 日韩 欧美 动漫 国产 制服 | 成人三级无码视频在线观看 | 伦伦影院午夜理论片 | 国产精品亚洲五月天高清 | 毛片内射-百度 | 亚洲成av人片天堂网无码】 | 熟妇女人妻丰满少妇中文字幕 | 日本大香伊一区二区三区 | 日本大乳高潮视频在线观看 | 亚洲中文字幕成人无码 | 国产午夜精品一区二区三区嫩草 | 强奷人妻日本中文字幕 | 四十如虎的丰满熟妇啪啪 | 波多野42部无码喷潮在线 | 大肉大捧一进一出视频出来呀 | 97久久精品无码一区二区 | 暴力强奷在线播放无码 | 亚洲小说春色综合另类 | 久久亚洲a片com人成 | 少妇被黑人到高潮喷出白浆 | 国产精品a成v人在线播放 | 天下第一社区视频www日本 | 小泽玛莉亚一区二区视频在线 | 人妻aⅴ无码一区二区三区 | 免费无码的av片在线观看 | 国产农村乱对白刺激视频 | 欧美 日韩 人妻 高清 中文 | 高中生自慰www网站 | 玩弄中年熟妇正在播放 | 少妇人妻大乳在线视频 | 久久国产36精品色熟妇 | 亚拍精品一区二区三区探花 | 欧美熟妇另类久久久久久不卡 | 亚洲国产精品美女久久久久 | 少妇的肉体aa片免费 | 图片区 小说区 区 亚洲五月 | 色综合久久久无码中文字幕 | 欧美精品国产综合久久 | 国产人妻久久精品二区三区老狼 | 精品久久久久香蕉网 | 国产乱人偷精品人妻a片 | 国产色视频一区二区三区 | 国产精品视频免费播放 | 国产精品久久久久久久9999 | 日韩精品一区二区av在线 | 漂亮人妻洗澡被公强 日日躁 | 国产莉萝无码av在线播放 | 日韩成人一区二区三区在线观看 | 日韩欧美成人免费观看 | 欧美 丝袜 自拍 制服 另类 | 欧美精品一区二区精品久久 | 欧美精品免费观看二区 | 色婷婷欧美在线播放内射 | 中文字幕精品av一区二区五区 | 综合网日日天干夜夜久久 | 国产人妻人伦精品1国产丝袜 | 乱人伦人妻中文字幕无码久久网 | 欧美 日韩 人妻 高清 中文 | 国产麻豆精品精东影业av网站 | 久久久久久久久蜜桃 | 亚洲日韩av一区二区三区四区 | 亚洲s码欧洲m码国产av | 色妞www精品免费视频 | 久久国产精品萌白酱免费 | 午夜精品一区二区三区的区别 | 亚洲色在线无码国产精品不卡 | 日韩欧美中文字幕公布 | 国产人妻大战黑人第1集 | 日韩少妇白浆无码系列 | 波多野结衣av在线观看 | 国产三级精品三级男人的天堂 | 国产亚洲日韩欧美另类第八页 | 蜜桃臀无码内射一区二区三区 | 99精品无人区乱码1区2区3区 | 伊人久久大香线蕉亚洲 | 天海翼激烈高潮到腰振不止 | 亚洲gv猛男gv无码男同 | 天天av天天av天天透 | 精品国精品国产自在久国产87 | 成年女人永久免费看片 | 无码av岛国片在线播放 | 天下第一社区视频www日本 | 国产va免费精品观看 | 少妇人妻av毛片在线看 | 丰满妇女强制高潮18xxxx | 女人和拘做爰正片视频 | 亚洲精品国产品国语在线观看 | 中文无码精品a∨在线观看不卡 | 亚洲国产综合无码一区 | 日本肉体xxxx裸交 | 激情亚洲一区国产精品 | 久久精品人妻少妇一区二区三区 | 国产凸凹视频一区二区 | 中文字幕av无码一区二区三区电影 | 久久综合色之久久综合 | 午夜福利试看120秒体验区 | 亚洲一区二区三区无码久久 | 亚洲国产精品久久久久久 | 黑人巨大精品欧美一区二区 | 99久久人妻精品免费一区 | 荫蒂被男人添的好舒服爽免费视频 | 成人无码精品一区二区三区 | 狠狠色噜噜狠狠狠狠7777米奇 | 国产精品无码一区二区三区不卡 | 国产午夜手机精彩视频 | 久久视频在线观看精品 | 日本大香伊一区二区三区 | 成人欧美一区二区三区 | 人人妻人人澡人人爽人人精品浪潮 | 国产莉萝无码av在线播放 | 2020久久超碰国产精品最新 | 又紧又大又爽精品一区二区 | 成人综合网亚洲伊人 | 欧美野外疯狂做受xxxx高潮 | 精品人人妻人人澡人人爽人人 | 精品无码国产一区二区三区av | 小鲜肉自慰网站xnxx | 亚洲精品综合五月久久小说 | 亚洲国产一区二区三区在线观看 | 中文字幕av伊人av无码av | 国产极品视觉盛宴 | 国产精品二区一区二区aⅴ污介绍 | 人妻天天爽夜夜爽一区二区 | 麻豆国产人妻欲求不满谁演的 | 正在播放老肥熟妇露脸 | 久久久久成人片免费观看蜜芽 | 久久久精品456亚洲影院 | 双乳奶水饱满少妇呻吟 | 丝袜足控一区二区三区 | 一区二区三区乱码在线 | 欧洲 | 久久视频在线观看精品 | 中文精品无码中文字幕无码专区 | 国产在线精品一区二区高清不卡 | 四虎永久在线精品免费网址 | 激情亚洲一区国产精品 | 男女爱爱好爽视频免费看 | 日本乱偷人妻中文字幕 | 久久人人爽人人爽人人片av高清 | 九九在线中文字幕无码 | 免费观看又污又黄的网站 | 日本va欧美va欧美va精品 | 人人爽人人爽人人片av亚洲 | 图片小说视频一区二区 | 人妻尝试又大又粗久久 | 国产亚洲精品久久久久久 | 曰本女人与公拘交酡免费视频 | 国产麻豆精品精东影业av网站 | 国产精品-区区久久久狼 | 综合激情五月综合激情五月激情1 | 人妻无码αv中文字幕久久琪琪布 | 久久99精品久久久久久动态图 | 日韩亚洲欧美精品综合 | 亚洲精品午夜无码电影网 | 久久久久久a亚洲欧洲av冫 | 亚洲色欲久久久综合网东京热 | 四虎影视成人永久免费观看视频 | 午夜无码区在线观看 | 无码一区二区三区在线观看 | 激情内射日本一区二区三区 | 中文字幕精品av一区二区五区 | 成人欧美一区二区三区 | 六十路熟妇乱子伦 | 岛国片人妻三上悠亚 | 秋霞成人午夜鲁丝一区二区三区 | 国产真人无遮挡作爱免费视频 | 少妇太爽了在线观看 | 欧洲精品码一区二区三区免费看 | 久久久国产一区二区三区 | 亚洲毛片av日韩av无码 | 亚洲熟妇自偷自拍另类 | 国产激情无码一区二区 | 18无码粉嫩小泬无套在线观看 | 久久久久亚洲精品中文字幕 | 欧美黑人乱大交 | 秋霞特色aa大片 | 国产三级精品三级男人的天堂 | 国产精品亚洲综合色区韩国 | 丰满岳乱妇在线观看中字无码 | 亚洲精品一区二区三区婷婷月 | 男女超爽视频免费播放 | 成人三级无码视频在线观看 | 东京无码熟妇人妻av在线网址 | 国产精品久久久久影院嫩草 | 亚洲综合另类小说色区 | 免费乱码人妻系列无码专区 | 亚洲男人av天堂午夜在 | 亚洲大尺度无码无码专区 | 国产精品福利视频导航 | 久久亚洲国产成人精品性色 | 久久久久久国产精品无码下载 | 久久精品女人的天堂av | 久久成人a毛片免费观看网站 | 精品无人区无码乱码毛片国产 | 嫩b人妻精品一区二区三区 | 丰腴饱满的极品熟妇 | 亚洲国产精品久久人人爱 | 亚洲欧美日韩国产精品一区二区 | 国产做国产爱免费视频 | 亚洲国产精品无码一区二区三区 | 亚洲熟女一区二区三区 | 九月婷婷人人澡人人添人人爽 | 奇米影视7777久久精品人人爽 | 大肉大捧一进一出视频出来呀 | 亚洲国产欧美在线成人 | 国产精品手机免费 | 国产97人人超碰caoprom | 一个人看的www免费视频在线观看 | 亚洲精品午夜无码电影网 | 国产小呦泬泬99精品 | 久久久久成人片免费观看蜜芽 | 午夜福利一区二区三区在线观看 | 国产亚洲人成a在线v网站 | 国产精品无码一区二区三区不卡 | 国产艳妇av在线观看果冻传媒 | 亚洲色欲久久久综合网东京热 | 亚洲精品中文字幕久久久久 | 久久综合香蕉国产蜜臀av | √天堂中文官网8在线 | 天天摸天天透天天添 | 中文字幕人成乱码熟女app | 久久综合色之久久综合 | 欧美日韩一区二区三区自拍 | 偷窥日本少妇撒尿chinese | 午夜无码人妻av大片色欲 | 熟妇人妻无码xxx视频 | 水蜜桃av无码 | 女人色极品影院 | 久久久av男人的天堂 | 国产人成高清在线视频99最全资源 | 在线观看国产一区二区三区 | 国产av久久久久精东av | 成人欧美一区二区三区黑人免费 | 国产福利视频一区二区 | 国产麻豆精品精东影业av网站 | 成人无码精品1区2区3区免费看 | 国产精品永久免费视频 | 自拍偷自拍亚洲精品被多人伦好爽 | 久久久久99精品国产片 | 欧美日韩视频无码一区二区三 | 麻豆成人精品国产免费 | 国産精品久久久久久久 | 一本一道久久综合久久 | 欧美日韩视频无码一区二区三 | 日本xxxx色视频在线观看免费 | 十八禁视频网站在线观看 | 成人免费视频一区二区 | 日本一卡二卡不卡视频查询 | 无码国模国产在线观看 | 国产人妻大战黑人第1集 | 2020最新国产自产精品 | 东北女人啪啪对白 | 成人女人看片免费视频放人 | 美女张开腿让人桶 | 亚洲精品一区国产 | 午夜无码人妻av大片色欲 | 国产精品无码mv在线观看 | 久久久av男人的天堂 | 欧美日本日韩 | 国产精品香蕉在线观看 | 5858s亚洲色大成网站www | 性色欲情网站iwww九文堂 | 天天摸天天碰天天添 | 蜜臀av无码人妻精品 | 国产97在线 | 亚洲 | 亚洲国产精品成人久久蜜臀 | 麻豆成人精品国产免费 | 秋霞特色aa大片 | 国产精品怡红院永久免费 | 国产精品久久久久久亚洲影视内衣 | 综合人妻久久一区二区精品 | 一本色道久久综合狠狠躁 | 在线观看免费人成视频 | 成人av无码一区二区三区 | 国精产品一品二品国精品69xx | 国产无遮挡又黄又爽又色 | 亚洲中文字幕久久无码 | 色狠狠av一区二区三区 | 最近中文2019字幕第二页 | 国产精品无码一区二区三区不卡 | 麻豆国产丝袜白领秘书在线观看 | 亚洲a无码综合a国产av中文 | 久久久久免费精品国产 | 色综合久久网 | 国产亚洲精品久久久久久 | 久久久精品456亚洲影院 | 男人扒开女人内裤强吻桶进去 | 亚洲无人区一区二区三区 | 丰满诱人的人妻3 | 日本一区二区三区免费播放 | 疯狂三人交性欧美 | 夜夜高潮次次欢爽av女 | 久久综合香蕉国产蜜臀av | 中文字幕人妻无码一夲道 | 日本高清一区免费中文视频 | 精品乱子伦一区二区三区 | 午夜福利试看120秒体验区 | 色婷婷欧美在线播放内射 | 日韩成人一区二区三区在线观看 | 永久黄网站色视频免费直播 | 亚洲精品国偷拍自产在线麻豆 | 天天做天天爱天天爽综合网 | 人人爽人人澡人人高潮 | 亚洲a无码综合a国产av中文 | 人人妻人人澡人人爽欧美一区 | 国产精品国产三级国产专播 | 青青草原综合久久大伊人精品 | 狂野欧美激情性xxxx | 亚洲精品国产精品乱码视色 | 欧美丰满老熟妇xxxxx性 | 亚洲s码欧洲m码国产av | 成人无码视频在线观看网站 | 欧美人与禽zoz0性伦交 | 狠狠色噜噜狠狠狠狠7777米奇 | 少妇性l交大片 | 性色欲情网站iwww九文堂 | 又湿又紧又大又爽a视频国产 | 日本丰满熟妇videos | 亚洲综合另类小说色区 | 狠狠亚洲超碰狼人久久 | 人妻与老人中文字幕 | 一本大道伊人av久久综合 | 国产成人久久精品流白浆 | 国产精品久久久久久亚洲影视内衣 | 国产综合久久久久鬼色 | 久久天天躁狠狠躁夜夜免费观看 | av无码电影一区二区三区 | 女人被爽到呻吟gif动态图视看 | 国产高潮视频在线观看 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 久久久久99精品成人片 | 国产亚洲欧美日韩亚洲中文色 | 国产乱码精品一品二品 | 国产三级久久久精品麻豆三级 | 成熟人妻av无码专区 | 中文字幕人妻无码一夲道 | 樱花草在线社区www | 亚洲色欲色欲欲www在线 | 亚洲日韩中文字幕在线播放 | 国产亲子乱弄免费视频 | 在线观看国产一区二区三区 | 精品国产福利一区二区 | 亚洲一区二区三区播放 | 俺去俺来也在线www色官网 | 88国产精品欧美一区二区三区 | 无码精品国产va在线观看dvd | 少妇人妻偷人精品无码视频 | 久久99久久99精品中文字幕 | 人人超人人超碰超国产 | 少妇性l交大片欧洲热妇乱xxx | 久久精品国产一区二区三区肥胖 | 超碰97人人做人人爱少妇 | 久久99精品久久久久婷婷 | 亚洲成色www久久网站 | 学生妹亚洲一区二区 | 久久精品国产99精品亚洲 | 免费无码午夜福利片69 | 最近中文2019字幕第二页 | 欧美日韩亚洲国产精品 | 美女黄网站人色视频免费国产 | 亚洲七七久久桃花影院 | 国内少妇偷人精品视频 | 少妇太爽了在线观看 | 欧美怡红院免费全部视频 | 亚洲人成影院在线无码按摩店 | 天天av天天av天天透 | 精品国精品国产自在久国产87 | 国产suv精品一区二区五 | 亚洲乱码中文字幕在线 | 亚洲欧美综合区丁香五月小说 | 色一情一乱一伦一视频免费看 | www国产亚洲精品久久久日本 | 一本久道高清无码视频 | 亚洲国产成人av在线观看 | 成人欧美一区二区三区 | 伊人久久婷婷五月综合97色 | 精品熟女少妇av免费观看 | 欧美丰满老熟妇xxxxx性 | 中文字幕av无码一区二区三区电影 | 久久国产精品二国产精品 | 鲁大师影院在线观看 | 1000部啪啪未满十八勿入下载 | 成人无码影片精品久久久 | 国产办公室秘书无码精品99 | 国产精品久久久久影院嫩草 | 久精品国产欧美亚洲色aⅴ大片 | 午夜福利一区二区三区在线观看 | 色欲综合久久中文字幕网 | 人妻天天爽夜夜爽一区二区 | 性欧美疯狂xxxxbbbb | 中文字幕精品av一区二区五区 | 日本www一道久久久免费榴莲 | 亚洲成av人在线观看网址 | 性欧美大战久久久久久久 | 亚洲爆乳精品无码一区二区三区 | 日韩av无码一区二区三区不卡 | 欧美亚洲国产一区二区三区 | 午夜丰满少妇性开放视频 | 狠狠综合久久久久综合网 | 久久精品丝袜高跟鞋 | 色五月五月丁香亚洲综合网 | 好男人www社区 | 亚洲熟悉妇女xxx妇女av | 国产婷婷色一区二区三区在线 | 天堂亚洲2017在线观看 | 少妇太爽了在线观看 | 性欧美熟妇videofreesex | 中文字幕av日韩精品一区二区 | 国产99久久精品一区二区 | 国产精品美女久久久久av爽李琼 | 3d动漫精品啪啪一区二区中 | 骚片av蜜桃精品一区 | 国産精品久久久久久久 | 久久亚洲精品中文字幕无男同 | 日日摸天天摸爽爽狠狠97 | 中文无码精品a∨在线观看不卡 | 精品偷拍一区二区三区在线看 | 久久久www成人免费毛片 | 久久综合网欧美色妞网 | 久久精品无码一区二区三区 | 久久www免费人成人片 | 美女扒开屁股让男人桶 | 久久精品99久久香蕉国产色戒 | 国产乱人无码伦av在线a | 亚洲欧美国产精品专区久久 | 国产凸凹视频一区二区 | 亚洲精品一区三区三区在线观看 | 1000部啪啪未满十八勿入下载 | 国产日产欧产精品精品app | 日本肉体xxxx裸交 | 亚洲成av人影院在线观看 | 色一情一乱一伦一区二区三欧美 | 精品国产一区二区三区四区在线看 | 午夜无码人妻av大片色欲 | 日本精品人妻无码免费大全 | 天天摸天天碰天天添 | 久久久久av无码免费网 | 少妇无套内谢久久久久 | 亚洲国精产品一二二线 | 天天躁夜夜躁狠狠是什么心态 | 国产成人av免费观看 | 美女极度色诱视频国产 | 国产成人精品一区二区在线小狼 | 狠狠噜狠狠狠狠丁香五月 | 国产精品va在线播放 | 国产莉萝无码av在线播放 | 色婷婷久久一区二区三区麻豆 | 色婷婷av一区二区三区之红樱桃 | 日日噜噜噜噜夜夜爽亚洲精品 | 内射巨臀欧美在线视频 | 狠狠噜狠狠狠狠丁香五月 | 亚洲精品鲁一鲁一区二区三区 | 成人无码影片精品久久久 | 最近的中文字幕在线看视频 | 亚洲一区av无码专区在线观看 | 日韩 欧美 动漫 国产 制服 | 亚洲熟悉妇女xxx妇女av | 亚洲国产精品成人久久蜜臀 | 伊人久久大香线蕉亚洲 | 久9re热视频这里只有精品 | 日韩av无码一区二区三区 | 国产精品久久久午夜夜伦鲁鲁 | 一本色道婷婷久久欧美 | 国产精品久久福利网站 | 玩弄少妇高潮ⅹxxxyw | 国产成人无码av在线影院 | 少妇无套内谢久久久久 | 特黄特色大片免费播放器图片 | 性色av无码免费一区二区三区 | 亚洲中文字幕在线无码一区二区 | 又紧又大又爽精品一区二区 | 国产猛烈高潮尖叫视频免费 | 高清国产亚洲精品自在久久 | 蜜桃视频插满18在线观看 | aⅴ在线视频男人的天堂 | 国精产品一品二品国精品69xx | 久久亚洲日韩精品一区二区三区 | 国产精品亚洲五月天高清 | 久久久中文字幕日本无吗 | 国产在线无码精品电影网 | 激情国产av做激情国产爱 | 成年女人永久免费看片 | 成人欧美一区二区三区 | 国产精品亚洲综合色区韩国 | 欧美日本免费一区二区三区 | 亚洲中文字幕成人无码 | 国产电影无码午夜在线播放 | 国产激情精品一区二区三区 | 又大又硬又黄的免费视频 | 国产午夜福利100集发布 | 无码纯肉视频在线观看 | 成人亚洲精品久久久久软件 | 国产精品国产自线拍免费软件 | 在线a亚洲视频播放在线观看 | 自拍偷自拍亚洲精品10p | 亚洲国产精品无码久久久久高潮 | 久久精品国产99久久6动漫 | 亚洲区欧美区综合区自拍区 | 乱码av麻豆丝袜熟女系列 | 日本www一道久久久免费榴莲 | 丰满岳乱妇在线观看中字无码 | 人妻少妇精品视频专区 | 色狠狠av一区二区三区 | 国产午夜福利亚洲第一 | 国产片av国语在线观看 | av人摸人人人澡人人超碰下载 | 性欧美videos高清精品 | 国产亚洲精品久久久久久大师 | 国产精品igao视频网 | 日本www一道久久久免费榴莲 | 亚洲成色在线综合网站 | 国产精品久久久久久亚洲影视内衣 | 无码国产色欲xxxxx视频 | 欧美性猛交内射兽交老熟妇 | 国语精品一区二区三区 | 男人的天堂2018无码 | 中文字幕无码免费久久9一区9 | 精品少妇爆乳无码av无码专区 | 亚洲中文字幕无码一久久区 | 久久精品中文字幕大胸 | 无码av岛国片在线播放 | 久久99精品国产.久久久久 | 中文字幕无码视频专区 | 亚洲欧美中文字幕5发布 | 亚洲日本va中文字幕 | 国产精品久久久久久久9999 | 福利一区二区三区视频在线观看 | 色婷婷综合激情综在线播放 | 亚洲一区二区三区偷拍女厕 | 国产人妻精品一区二区三区 | 无遮挡啪啪摇乳动态图 | 乱人伦人妻中文字幕无码久久网 | 国产人妻精品一区二区三区不卡 | 人妻互换免费中文字幕 | 久久97精品久久久久久久不卡 | 亚洲精品中文字幕 | 国产口爆吞精在线视频 | 99精品国产综合久久久久五月天 | 婷婷综合久久中文字幕蜜桃三电影 | 又大又硬又爽免费视频 | 无码精品人妻一区二区三区av | 亚洲国产精品成人久久蜜臀 | 天堂亚洲2017在线观看 | 图片小说视频一区二区 | 国产成人无码区免费内射一片色欲 | 国产激情无码一区二区 | 丝袜足控一区二区三区 | 日韩精品无码免费一区二区三区 | 免费人成在线观看网站 | 1000部啪啪未满十八勿入下载 | 国产成人无码av一区二区 | 日韩在线不卡免费视频一区 | 男女爱爱好爽视频免费看 | 久久99精品国产.久久久久 | 三级4级全黄60分钟 | 午夜免费福利小电影 | 曰本女人与公拘交酡免费视频 | 婷婷综合久久中文字幕蜜桃三电影 | 色欲人妻aaaaaaa无码 | 中文久久乱码一区二区 | 日本一区二区三区免费高清 | 香蕉久久久久久av成人 | 精品国产一区二区三区四区在线看 | av人摸人人人澡人人超碰下载 | 国产亚洲精品久久久ai换 | 少妇性荡欲午夜性开放视频剧场 | 免费乱码人妻系列无码专区 | 人人爽人人澡人人人妻 | 久久国产精品偷任你爽任你 | 无人区乱码一区二区三区 | 无码人妻精品一区二区三区不卡 | 黄网在线观看免费网站 | 国产疯狂伦交大片 | 亚洲精品中文字幕久久久久 | 波多野结衣av一区二区全免费观看 | 亚洲综合无码久久精品综合 | 福利一区二区三区视频在线观看 | 狠狠色欧美亚洲狠狠色www | 精品国产成人一区二区三区 | 国产超级va在线观看视频 | 欧美三级a做爰在线观看 | 久久人人爽人人人人片 | 国产精品亚洲一区二区三区喷水 | 中文毛片无遮挡高清免费 | 久久亚洲日韩精品一区二区三区 | 无码人妻精品一区二区三区不卡 | 狠狠亚洲超碰狼人久久 | 男人的天堂2018无码 | 88国产精品欧美一区二区三区 | 亚洲精品一区二区三区在线观看 | 天天躁夜夜躁狠狠是什么心态 | 中文精品久久久久人妻不卡 | 乱人伦人妻中文字幕无码 | 麻豆果冻传媒2021精品传媒一区下载 | 自拍偷自拍亚洲精品被多人伦好爽 | 国产精品久久久 | 欧美野外疯狂做受xxxx高潮 | 亚洲日韩中文字幕在线播放 | 狠狠噜狠狠狠狠丁香五月 | 久久午夜夜伦鲁鲁片无码免费 | 青青青爽视频在线观看 | 亚洲欧美精品伊人久久 | 无码精品国产va在线观看dvd | 又大又硬又爽免费视频 | 亚洲日本va中文字幕 | 97夜夜澡人人爽人人喊中国片 | 欧美激情内射喷水高潮 | 黑人巨大精品欧美一区二区 | 亚洲精品午夜无码电影网 | 成人毛片一区二区 | 国产亚洲精品久久久久久 | 撕开奶罩揉吮奶头视频 | 久久精品中文字幕大胸 | 88国产精品欧美一区二区三区 | 人妻体内射精一区二区三四 | 国产偷国产偷精品高清尤物 | 牛和人交xxxx欧美 | 夜夜夜高潮夜夜爽夜夜爰爰 | 麻花豆传媒剧国产免费mv在线 | 国产精品高潮呻吟av久久 | 国产suv精品一区二区五 | 国产美女精品一区二区三区 | 中文字幕乱妇无码av在线 | 波多野结衣 黑人 | 日韩人妻无码中文字幕视频 | 国产精品亚洲lv粉色 | 麻豆国产97在线 | 欧洲 | 少妇性俱乐部纵欲狂欢电影 | 曰韩无码二三区中文字幕 | 成人免费视频视频在线观看 免费 | 成人无码影片精品久久久 | 装睡被陌生人摸出水好爽 | 精品国产av色一区二区深夜久久 | 国产成人av免费观看 | 任你躁国产自任一区二区三区 | 久久久久久亚洲精品a片成人 | 国产 精品 自在自线 | 色老头在线一区二区三区 | 国产9 9在线 | 中文 | 久久精品人人做人人综合 | 久久人人爽人人爽人人片av高清 | 最新国产麻豆aⅴ精品无码 | 97人妻精品一区二区三区 | 欧美 丝袜 自拍 制服 另类 | 美女毛片一区二区三区四区 | 久久久久久久久888 | 乌克兰少妇性做爰 | www国产亚洲精品久久久日本 | 国产舌乚八伦偷品w中 | 欧美三级不卡在线观看 | 内射巨臀欧美在线视频 | 欧美激情一区二区三区成人 | 色综合久久久无码网中文 | 国产电影无码午夜在线播放 | www国产亚洲精品久久久日本 | 国产舌乚八伦偷品w中 | 亚洲理论电影在线观看 | 对白脏话肉麻粗话av | 中文字幕av伊人av无码av | 成人无码精品一区二区三区 | 内射老妇bbwx0c0ck | 国产后入清纯学生妹 | 人妻插b视频一区二区三区 | 免费无码午夜福利片69 | 夜精品a片一区二区三区无码白浆 | 欧美一区二区三区视频在线观看 | 最新国产麻豆aⅴ精品无码 | 国产suv精品一区二区五 | 久久无码人妻影院 | 图片区 小说区 区 亚洲五月 | 亚洲精品欧美二区三区中文字幕 | 亚洲а∨天堂久久精品2021 | 国产热a欧美热a在线视频 | 欧美第一黄网免费网站 | 乌克兰少妇性做爰 | 国产乱人无码伦av在线a | 夜精品a片一区二区三区无码白浆 | 日韩av无码一区二区三区 | 精品厕所偷拍各类美女tp嘘嘘 | 亚洲精品无码国产 | 成人片黄网站色大片免费观看 | 国产麻豆精品精东影业av网站 | 日本精品高清一区二区 | 亚洲色成人中文字幕网站 | 成人av无码一区二区三区 | 国产精品99久久精品爆乳 | 精品人妻中文字幕有码在线 | 俄罗斯老熟妇色xxxx | 成人无码影片精品久久久 | 久久久精品人妻久久影视 | 成年美女黄网站色大免费视频 | 永久免费观看美女裸体的网站 | 少妇性l交大片欧洲热妇乱xxx | 亚洲国产精品久久人人爱 | 国产精品久久久久无码av色戒 | 狂野欧美性猛xxxx乱大交 | 国产成人无码a区在线观看视频app | 欧美午夜特黄aaaaaa片 | 久久久婷婷五月亚洲97号色 | 99麻豆久久久国产精品免费 | 蜜桃视频插满18在线观看 | 欧洲美熟女乱又伦 | 青草青草久热国产精品 | 国色天香社区在线视频 | 奇米影视7777久久精品 | 久久天天躁狠狠躁夜夜免费观看 | 午夜时刻免费入口 | 天天躁夜夜躁狠狠是什么心态 | 国产绳艺sm调教室论坛 | 偷窥村妇洗澡毛毛多 | 欧美日韩一区二区三区自拍 | 久久久久se色偷偷亚洲精品av | 国产亚洲人成a在线v网站 | 亚洲成a人片在线观看无码 | 强开小婷嫩苞又嫩又紧视频 | 久久国产精品二国产精品 | 沈阳熟女露脸对白视频 | 熟女少妇人妻中文字幕 | 亚洲国产精品一区二区美利坚 | 香港三级日本三级妇三级 | 亚洲性无码av中文字幕 | 麻豆人妻少妇精品无码专区 | 国产精品va在线播放 | 99er热精品视频 | 无码乱肉视频免费大全合集 | 精品国产青草久久久久福利 | 97无码免费人妻超级碰碰夜夜 | 无码帝国www无码专区色综合 | 亚洲区欧美区综合区自拍区 | 天干天干啦夜天干天2017 | 人人妻人人澡人人爽人人精品浪潮 | 精品无码国产自产拍在线观看蜜 | 18无码粉嫩小泬无套在线观看 | 在线播放免费人成毛片乱码 | 国产深夜福利视频在线 | 乱码av麻豆丝袜熟女系列 | 日韩精品久久久肉伦网站 | 亚洲一区二区观看播放 | 欧美人与动性行为视频 | 色综合久久中文娱乐网 | 国产精品高潮呻吟av久久 | 俺去俺来也www色官网 | 在线欧美精品一区二区三区 | 久久99精品久久久久久动态图 | 亚洲国产精品无码久久久久高潮 | 国产无套粉嫩白浆在线 | 亚洲人成人无码网www国产 | 久久99精品久久久久久 | 精品无码av一区二区三区 | 国产精品人人爽人人做我的可爱 | 亚洲理论电影在线观看 | 波多野结衣一区二区三区av免费 | 又紧又大又爽精品一区二区 | 高潮毛片无遮挡高清免费视频 | 欧美人与牲动交xxxx | 无码福利日韩神码福利片 | 一本加勒比波多野结衣 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 无码福利日韩神码福利片 | 精品国产青草久久久久福利 | 无码成人精品区在线观看 | 国产精品二区一区二区aⅴ污介绍 | 免费国产成人高清在线观看网站 | 狂野欧美性猛交免费视频 | 欧美老熟妇乱xxxxx | 亚洲娇小与黑人巨大交 | 在线观看国产一区二区三区 | 国内丰满熟女出轨videos | 亚洲欧美精品伊人久久 | 日本肉体xxxx裸交 | 亚洲熟悉妇女xxx妇女av | 国产亚洲日韩欧美另类第八页 | 97久久超碰中文字幕 | 性色av无码免费一区二区三区 | 一本久久a久久精品vr综合 | 欧美自拍另类欧美综合图片区 | 中国女人内谢69xxxxxa片 | 久久久久久国产精品无码下载 | 啦啦啦www在线观看免费视频 | 亚洲成av人综合在线观看 | 亚洲天堂2017无码 | 无码吃奶揉捏奶头高潮视频 | 国产激情一区二区三区 | 国产精品无码永久免费888 | 久久久久人妻一区精品色欧美 | 任你躁国产自任一区二区三区 | www一区二区www免费 | 大肉大捧一进一出好爽视频 | 又湿又紧又大又爽a视频国产 | 国产精品丝袜黑色高跟鞋 | 狠狠色噜噜狠狠狠狠7777米奇 | 欧美 丝袜 自拍 制服 另类 | 亚洲人成人无码网www国产 | 无码吃奶揉捏奶头高潮视频 | 亚洲国产精品无码一区二区三区 | 精品国产一区二区三区av 性色 | 婷婷丁香五月天综合东京热 | 日日天干夜夜狠狠爱 | 国产成人精品久久亚洲高清不卡 | 午夜嘿嘿嘿影院 | 国产午夜亚洲精品不卡下载 |