內(nèi)存空間的正確理解

理解、正確運(yùn)用計(jì)算機(jī)內(nèi)存

引言

在最近學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和與同學(xué)交流問(wèn)題過(guò)程中士嚎,發(fā)現(xiàn)了一個(gè)極具普遍性的問(wèn)題呜魄,那就是為什么把一些代碼塊獨(dú)立出來(lái)做成一個(gè)函數(shù)就會(huì)出現(xiàn)問(wèn)題,而不做成函數(shù)反而沒(méi)問(wèn)題莱衩?難道這是要我們反對(duì)使用函數(shù)嗎爵嗅?不! 不是這樣的笨蚁,在閱讀完相關(guān)資料后睹晒,我發(fā)現(xiàn)其實(shí)是同學(xué)們對(duì)內(nèi)存空間的理解不夠,說(shuō)通俗點(diǎn)就是不知道內(nèi)存空間長(zhǎng)啥樣括细。那接下來(lái)我將給大家講解一下幾種對(duì)內(nèi)存的錯(cuò)誤操作以及幾種合理地解決方案伪很,從而讓大家對(duì)內(nèi)存空間有更好的理解。當(dāng)然以下的理解或多或少敘述上有失嚴(yán)謹(jǐn)?shù)牡胤椒艿ィ@些都是基于我自己對(duì)與內(nèi)存空間的理解锉试,希望讀者諒解并指出。

內(nèi)存空間

一般筆記本的內(nèi)存(RAM)有4G或8G览濒。它分為5大區(qū)域呆盖,分別是代碼區(qū)、全局?jǐn)?shù)據(jù)空間匾七、堆空間絮短、棧空間昨忆、內(nèi)核空間丁频。它們的圖例如下(以4G內(nèi)存為例):

內(nèi)存分布圖.png

棧與堆

我們從最常聽(tīng)到的棧空間與堆空間開(kāi)始邑贴。堆空間和椣铮空間統(tǒng)稱(chēng)為動(dòng)態(tài)儲(chǔ)存空間,它們分擔(dān)著儲(chǔ)存程序運(yùn)行時(shí)產(chǎn)生的變量的任務(wù)拢驾。就椊贝牛空間來(lái)說(shuō),可以這樣理解:函數(shù)先運(yùn)行main函數(shù)繁疤,則先把main函數(shù)放進(jìn)椏空間秕狰,同時(shí)把main函數(shù)里面聲明的變量全部包含在其中,當(dāng)main函數(shù)結(jié)束時(shí)(當(dāng)然也是程序結(jié)束時(shí))躁染,則把main函數(shù)拿出棧(此時(shí)顯然除了main函數(shù)其他函數(shù)都已結(jié)束)鸣哀,并同時(shí)把主函數(shù)里面的變量“帶走”。所謂“帶走”就是說(shuō)在后續(xù)操作中就再也不能使用這些變量了吞彤,就像下面的例子我衬,在調(diào)用完Max函數(shù)后printf("%d",max);是錯(cuò)誤的:

#include <stdio.h>

int Max(int a,int b){
    int max;
    max=a>b?a:b;
    return max;
}

int main(void){
    int a,b,mmax;
    scanf("%d%d",&a,&b);
    mmax=Max(a,b);
    printf("%d",mmax);
    return 0;
}

當(dāng)程序運(yùn)行時(shí),必然先運(yùn)行main函數(shù)饰恕,于是先把main函數(shù)放進(jìn)椖痈幔空間,同時(shí)把main函數(shù)里面聲明的變量全部包含在其中埋嵌。當(dāng)程序進(jìn)行到調(diào)用Max函數(shù)時(shí)破加,又把Max函數(shù)壓入棧空間莉恼,同時(shí)把Max函數(shù)里面聲明的變量全部包含在其中拌喉。以次類(lèi)推,如果是在調(diào)用函數(shù)A時(shí)俐银,在A(yíng)函數(shù)里面又調(diào)用B函數(shù)尿背,則棧空間的堆放順序則是main函數(shù)在棧底捶惜,接著是A函數(shù)田藐,再者是B函數(shù)。如果是在調(diào)用完A函數(shù)后吱七,main函數(shù)再調(diào)用B函數(shù)汽久,則棧空間的操作方式是main函數(shù)先壓入棧底踊餐,再A函數(shù)壓入棧景醇,而后A函數(shù)拿出棧,最后B函數(shù)再壓入棧吝岭。于是乎三痰,我們就可以理解一類(lèi)函數(shù)的錯(cuò)誤所在了。如下為鏈?zhǔn)骄€(xiàn)性表的插入元素操作函數(shù):

#include <stdio.h>
#include<stdlib.h>
#include<time.h>

typedef struct NODE {
  struct NODE *next;
  int value;
} Node;

typedef enum { ERROR = 0, OK = 1 } Status;

Status Insert1(Node **ppLink,int newValue){
    Node new, *current;

    new.value = newValue;

    while(current=*ppLink,current!=NULL&&current->value<newValue){
        ppLink = &current->next;
    }

    *ppLink = new;
    new.next = current;

    return OK;
}
Insert函數(shù).png

初看起來(lái)我們好像成功地將新元素插入鏈表之中窜管。但是!結(jié)果恰恰相反获搏。我們使得鏈表斷截了失乾,因?yàn)槲覀僆nsert函數(shù)里面的new是局部變量3N酢@俣睢募壕!所以在函數(shù)結(jié)束時(shí)new所占用的棧內(nèi)存將被銷(xiāo)毀,于是乎鏈表就被斷了4汀!以下是錯(cuò)誤運(yùn)用此函數(shù)導(dǎo)致的錯(cuò)誤輸出結(jié)果(錯(cuò)誤的程序):

94 21 11 99 37 68 19 62 61 10//亂序鏈表
10 11 19 21 37 61 62 68 94 99//排序好的鏈表
10 11 19 10 0//錯(cuò)誤插入函數(shù)(試圖插入新元素20)導(dǎo)致的結(jié)果

20 24 32 5 44 17 72 26 99 32//亂序鏈表
5 17 20 24 26 32 32 44 72 99//排序好的鏈表
5 17 32 0//錯(cuò)誤插入函數(shù)(試圖插入新元素20)導(dǎo)致的結(jié)果

46 96 22 19 63 26 82 24 3 36//亂序鏈表
3 19 22 24 26 36 46 63 82 96//排序好的鏈表
3 19 36 0//錯(cuò)誤插入函數(shù)(試圖插入新元素20)導(dǎo)致的結(jié)果

從以上幾個(gè)輸出結(jié)果可以看出錯(cuò)誤插入函數(shù)導(dǎo)致的結(jié)果還不僅僅是將鏈表斷開(kāi)那么簡(jiǎn)單,其結(jié)果是很復(fù)雜的、莫名奇妙的。那么如何解決這個(gè)問(wèn)題呢凿试?国觉?接著我們就將介紹堆空間地用法:

查看網(wǎng)上對(duì)棧與堆的區(qū)別與聯(lián)系請(qǐng)戳這里傲醉。總而言之,結(jié)合前面的內(nèi)存分布圖,我們可以這樣理解堆空間:可以簡(jiǎn)單地理解為malloc區(qū)沪羔,也即保存malloc函數(shù)占用的內(nèi)存溉委,用free釋放。若程序員不釋放的話(huà)越除,程序結(jié)束時(shí)可能由OS(操作系統(tǒng))回收。

所以,malloc出來(lái)的內(nèi)存不會(huì)因?yàn)楹瘮?shù)結(jié)束而消失。因而只要將上Insert函數(shù)稍加改變就能夠使程序得出理想的結(jié)果(只要將Node new改成Node *new然后后面再malloc一塊內(nèi)存就行了):

//malloc版本
Status Insert1(Node **ppLink,int newValue){//可重復(fù)調(diào)用
    Node *new, *current;

    new = (Node *)malloc(sizeof(Node));
    if(new==NULL){
        return ERROR;
    }
    new->value = newValue;

    while(current=*ppLink,current!=NULL&&current->value<newValue){
        ppLink = &current->next;
    }

    *ppLink = new;
    new->next = current;

    return OK;
}

以下是程序運(yùn)行結(jié)果:

66 14 19 69 33 51 51 95 24 4//亂序鏈表
4 14 19 24 33 51 51 66 69 95//排序好的鏈表
4 14 19 20 24 33 51 51 66 69 95//成功將新元素20插入

到這里糕伐,或許還有同學(xué)對(duì)此嗤之以鼻:你說(shuō)的我都會(huì)呀!難道就這樣就能完全理解并運(yùn)用內(nèi)存了嗎?

問(wèn)的好澳骤,所以說(shuō)對(duì)于上述Insert函數(shù)地修改方案絕對(duì)不止堆空間方案一種。我們還可以運(yùn)用靜態(tài)空間舍哄。

bss區(qū)與data區(qū)

其實(shí)這兩個(gè)區(qū)儲(chǔ)存的變量類(lèi)型完全相同宴凉,都是儲(chǔ)存全局變量和靜態(tài)變量的內(nèi)存,所以我們大可把兩者看成同一塊區(qū)域丧靡。但是從很淺的方面講舟山,它們有一個(gè)很大的不同之處拆融,那就是bss區(qū)只儲(chǔ)存未初始化或初始化為0的全局變量和靜態(tài)變量,而data區(qū)則儲(chǔ)存 已初始化的全局變量和靜態(tài)變量但是除了const型的已初始化的全局變量镜豹。講到這里泰讽,大家或許迫不及待地想運(yùn)用靜態(tài)變量解決上述Insert函數(shù)的問(wèn)題了。那么如何運(yùn)用呢?因?yàn)殪o態(tài)空間也不屬于棧區(qū)菇绵,所以當(dāng)調(diào)用完一個(gè)函數(shù)時(shí)肄渗,函數(shù)里面申明的靜態(tài)變量是不會(huì)隨之銷(xiāo)毀的。于是乎我們得出將一個(gè)新元素插入鏈表的函數(shù):

//static版本
Status Insert1(Node **ppLink,int newValue){//只能調(diào)用一次
    static Node new;
    Node *current;

    new.value = newValue;

    while(current=*ppLink,current!=NULL&&current->value<newValue){
        ppLink = &current->next;
    }

    *ppLink = new;
    new.next = current;

    return OK;
}

以下是程序運(yùn)行結(jié)果:

29 70 61 85 68 67 72 87 59 95//亂序鏈表
29 59 61 67 68 70 72 85 87 95//排序好的鏈表
20 29 59 61 67 68 70 72 85 87 95//成功將新元素20插入

但是咬最,別高興地太早翎嫡。細(xì)心的同學(xué)可能注意到了malloc版本有“可重復(fù)調(diào)用”的字樣而static版本卻是“只能調(diào)用一次”。那么為什么會(huì)這樣呢永乌?這里就必須講清楚動(dòng)態(tài)空間與靜態(tài)空間的區(qū)別了惑申。一般說(shuō)來(lái),靜態(tài)空間的變量?jī)?nèi)存在程序一開(kāi)始就分配好了翅雏,在程序運(yùn)行時(shí)不能夠再聲明同一類(lèi)靜態(tài)變量多次圈驼。也就是說(shuō),當(dāng)程序第二次調(diào)用static版本的函數(shù)時(shí)望几,再次遇到

static Node new;

時(shí)绩脆,并不會(huì)再申請(qǐng)一塊靜態(tài)空間的內(nèi)存,而是對(duì)同一個(gè)new變量進(jìn)行操作橄抹。這也就為什么我們可以用static變量記錄調(diào)用函數(shù)的次數(shù)靴迫。

講到這里,我們又不得不提一下全局變量楼誓。關(guān)于這點(diǎn)最近有了一些感悟玉锌。有編程經(jīng)驗(yàn)以及參加過(guò)ACM程序設(shè)計(jì)比賽的同學(xué)們都知道,有時(shí)候我們需要申請(qǐng)一塊很大的內(nèi)存空間(如數(shù)組)來(lái)使用疟羹。但是在main函數(shù)里面申明一塊很大的內(nèi)存空間顯然不明智主守。因?yàn)閙ain函數(shù)里面的變量?jī)?nèi)存都是在棧空間里面的榄融,所以申請(qǐng)大內(nèi)存最好是全局變量参淫。以下是網(wǎng)上對(duì)此的解釋?zhuān)?/p>

全局變量在靜態(tài)存儲(chǔ)區(qū)分配內(nèi)存,局部變量是在棧上分配內(nèi)存空間的剃袍,這么大的數(shù)組放到棧上不溢出嗎黄刚?VC堆棧默認(rèn)是1M,int a[1000000]的大小是4*1000000民效,將近4M憔维,遠(yuǎn)遠(yuǎn)大于1M,編譯連接的時(shí)候不會(huì)有問(wèn)題畏邢,但運(yùn)行是堆棧溢出业扒,程序異常終止。如果你真的需要在堆棧上使用這么大的數(shù)組舒萎,那么可以在工程選項(xiàng)鏈接屬性里設(shè)置合適的堆棧大小程储。

但是作為一名程序員,我們往往會(huì)聽(tīng)到我們老師們或?qū)W長(zhǎng)學(xué)姐們或書(shū)上說(shuō)寫(xiě)程序時(shí)最好不要用全局變量。這就很有意思了章鲤,因?yàn)榇_實(shí)全局變量很容易出問(wèn)題摊灭。關(guān)于全局變量為什么危險(xiǎn)在這里我就不在贅述,讀者自行上網(wǎng)查找败徊,這里有一篇我上網(wǎng)查的比較容易理解的文章帚呼。那么,如果我一定要使用一塊大內(nèi)存空間但是又不能用全局變量皱蹦,我該怎么辦煤杀?仔細(xì)想想,不覺(jué)得想起了我的編程啟蒙老師張學(xué)沪哺,他對(duì)學(xué)生很?chē)?yán)格沈自,甚至可以說(shuō)有些“吝嗇”,但是如果上課真正地認(rèn)真做筆記辜妓,學(xué)習(xí)他的程序設(shè)計(jì)方法枯途,你會(huì)發(fā)現(xiàn)你受益無(wú)窮,而并不只是期末C語(yǔ)言能拿個(gè)高分而已籍滴。好了柔袁,接下來(lái)就是方法的講解:

我們的確可以在main函數(shù)里面申請(qǐng),但是异逐,我們要聲明的不是如下的樣子:

···
int main(void){
    int a[1000000];
    ···
}

我們應(yīng)該在main函數(shù)里面聲明一個(gè)int型的指針,然后再使用malloc函數(shù)插掂。對(duì)灰瞻,相信有的讀者已經(jīng)理解其中的精妙之處,修改后的代碼長(zhǎng)這樣:

···
int main(void){
    int *a;
    a=(int*)malloc(1000000*sizeof(int));
    if(a==NULL){
        printf("申請(qǐng)內(nèi)存失敻ㄉ酝润!");
        return 1;
    }
    ···
}

如果已經(jīng)看懂了文章前面關(guān)于堆空間的描述,那么就不會(huì)有懷疑了璃弄。在修改后的版本中要销,a是一個(gè)指針,在main函數(shù)里面聲明一個(gè)指針變量顯然是完全夠用的夏块。接著我們?cè)诙芽臻g里面malloc一塊1000000*sizeof(int)個(gè)字節(jié)內(nèi)存疏咐,在讓a指向這塊內(nèi)存。如此脐供,我們就可以像操作數(shù)組那樣進(jìn)行操作了浑塞。還有一個(gè)好處就是我們也不怎么用擔(dān)心訪(fǎng)問(wèn)“數(shù)組”不夠用了,因?yàn)槿绻鹠alloc出來(lái)的區(qū)域用完了政己,我們還可以用realloc函數(shù)為“數(shù)組”加長(zhǎng)酌壕。

text區(qū)

text區(qū)又稱(chēng)ROTEXT區(qū),其中RO的意思是Read Only(只讀)。那么這塊內(nèi)存是什么卵牍?又有什么用處果港?text區(qū)分為只讀數(shù)據(jù)段和代碼段。其中前者為保存程序文件中字符串內(nèi)容的空間以及const型的全局變量糊昙。而代碼段也就是整個(gè)程序文件的代碼辛掠。在以下的代碼中可以更好的理解:


內(nèi)存分布圖.png
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const int    g_A       = 10;         //text區(qū)
int          g_B       = 20;         //data區(qū)
static int   g_C       = 30;         //data區(qū)
static int   g_D;                    //BSS區(qū)
int          g_E;                    //BSS區(qū)
char        *p1;                     //BSS區(qū)
const char *ch[]={"Mon","Tus","Wed","Thu","Fri","Sat","Sun"};
//ch和Mon、Tus溅蛉、Wed公浪、Thu、Fri船侧、Sat欠气、Sun都在text區(qū)

int main( )
{
    int           local_A;            //棧
    int           local_B;            //棧
    static int    local_C = 0;        //data區(qū)
    static int    local_D;            //data區(qū)

    char        *p3 = "123456";     //123456在text區(qū),p3在棧上

    p1 = (char *)malloc( 10 );      //堆镜撩,分配得來(lái)得10字節(jié)的區(qū)域在堆區(qū)
    strcpy( p1, "123456" );         //123456{post.content}放在常量區(qū)预柒,編譯器可能會(huì)將它與p3所指向 的"123456"優(yōu)化成一塊

    printf("hight address\n");
    printf("-------------棧--------------\n");
    printf( "棧,    局部變量,                           local_A, addr:0x%08x\n", &local_A );
    printf( "棧,    局部變量,(后進(jìn)棧地址相對(duì)local_A低)  local_B, addr:0x%08x\n", &local_B );
    printf("-------------堆--------------\n");
    printf( "堆,    malloc分配內(nèi)存,             p1,      addr:0x%08x\n", p1 );
    printf("------------BSS區(qū)------------\n");
    printf( "BSS區(qū), 全局變量,       未初始化    g_E,     addr:0x%08x\n", &g_E, g_E );
    printf( "BSS區(qū), 靜態(tài)全局變量,   未初始化,   g_D,     addr:0x%08x\n", &g_D );
    printf( "BSS區(qū), 靜態(tài)局部變量,   初始化,     local_C, addr:0x%08x\n", &local_C);
    printf( "BSS區(qū), 靜態(tài)局部變量,   未初始化,   local_D, addr:0x%08x\n", &local_D);
    printf("-----------data區(qū)------------\n");
    printf( "data區(qū),全局變量,       初始化      g_B,     addr:0x%08x\n", &g_B);
    printf( "data區(qū),靜態(tài)全局變量,   初始化,     g_C,     addr:0x%08x\n", &g_C);
    printf("-----------text區(qū)------------\n");
    printf( "text區(qū),全局初始化變量, 只讀const,  g_A,     addr:0x%08x\n\n", &g_A);
    printf("low address\n");
    return 0;
}

以下是輸出結(jié)果:

hight address
-------------棧--------------
棧,    局部變量,                           local_A, addr:0x0062fe44
棧,    局部變量,(后進(jìn)棧地址相對(duì)local_A低)  local_B, addr:0x0062fe40
-------------堆--------------
堆,    malloc分配內(nèi)存,             p1,      addr:0x001e13e0
------------BSS區(qū)------------
BSS區(qū), 全局變量,       未初始化    g_E,     addr:0x00407030
BSS區(qū), 靜態(tài)全局變量,   未初始化,   g_D,     addr:0x00407040
BSS區(qū), 靜態(tài)局部變量,   初始化,     local_C, addr:0x00407044
BSS區(qū), 靜態(tài)局部變量,   未初始化,   local_D, addr:0x00407048
-----------data區(qū)------------
data區(qū),全局變量,       初始化      g_B,     addr:0x00403020
data區(qū),靜態(tài)全局變量,   初始化,     g_C,     addr:0x00403024
-----------text區(qū)------------
text區(qū),全局初始化變量, 只讀const,  g_A,     addr:0x00404348

low address

結(jié)語(yǔ)

emmmm,敲文字敲得老闊疼。不管怎樣我覺(jué)得多寫(xiě)總結(jié)(不是那種簡(jiǎn)單的筆記袁梗,而更像是給別人講解)可以讓我更好地深入理解知識(shí)宜鸯,這讓我受益匪淺。不管有沒(méi)有很多人看我的文章遮怜,我的學(xué)習(xí)目的已經(jīng)達(dá)到了淋袖,這是最讓我開(kāi)心的。當(dāng)然锯梁,能夠幫助對(duì)相關(guān)知識(shí)有問(wèn)題的同學(xué)那就更好了即碗。最后祭上我的新晉女神:

石原里美
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市陌凳,隨后出現(xiàn)的幾起案子剥懒,更是在濱河造成了極大的恐慌,老刑警劉巖合敦,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件初橘,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡充岛,警方通過(guò)查閱死者的電腦和手機(jī)保檐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)裸准,“玉大人展东,你說(shuō)我怎么就攤上這事〕淳悖” “怎么了盐肃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵爪膊,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我砸王,道長(zhǎng)推盛,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任谦铃,我火速辦了婚禮耘成,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘驹闰。我一直安慰自己瘪菌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布嘹朗。 她就那樣靜靜地躺著师妙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屹培。 梳的紋絲不亂的頭發(fā)上默穴,一...
    開(kāi)封第一講書(shū)人閱讀 51,258評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音褪秀,去河邊找鬼蓄诽。 笑死,一個(gè)胖子當(dāng)著我的面吹牛媒吗,可吹牛的內(nèi)容都是我干的仑氛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闸英,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼调衰!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起自阱,我...
    開(kāi)封第一講書(shū)人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎米酬,沒(méi)想到半個(gè)月后沛豌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赃额,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年加派,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跳芳。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芍锦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出飞盆,到底是詐尸還是另有隱情娄琉,我是刑警寧澤次乓,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站孽水,受9級(jí)特大地震影響票腰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜女气,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一杏慰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧炼鞠,春花似錦缘滥、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至瘩将,卻和暖如春吟税,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姿现。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工肠仪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人备典。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓异旧,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親提佣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吮蛹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容