CSAPP之詳解MollocLab

實(shí)驗(yàn)材料與規(guī)則

官網(wǎng)的實(shí)習(xí)手冊(cè)是缺了測(cè)試材料的,所以我建議你直接從這里下載吧:
https://github.com/happysnaker/CSAPPLabs/tree/CSAPP/molloc-Lab

實(shí)驗(yàn)僅要求我們修改mm.c文件,要求完成init, molloc, free, recalloc 四個(gè)函數(shù)肚医,其中部分與系統(tǒng)接口的函數(shù)已在memlib.c文件中給出赡鲜。

完成之后巩趁,我們需要鍵入以下三條命令來(lái)跑分:

make clean
make mdriver
./mdriver

這個(gè)實(shí)驗(yàn)難度特別大亦歉,其中非常容易碰到段錯(cuò)誤,以至于我最后一個(gè)分離式的鏈表仍然沒(méi)有實(shí)現(xiàn)劲腿,實(shí)乃一個(gè)遺憾。立個(gè)flag鸟妙,2021年一定要實(shí)現(xiàn)它焦人!

實(shí)驗(yàn)部分

隱式空閑鏈表加首次適配

首次適配從頭遍歷鏈表,找到空閑塊重父。這個(gè)跑分不是很理想花椭,甚至還不及格,只有56分房午。這個(gè)就是書(shū)上的思路个从,其中要自己完善兩個(gè)函數(shù)。
代碼:隱式空閑鏈表加首次適配實(shí)現(xiàn)

隱式空閑鏈表加下一次次適配

下一次適配從上次操作的時(shí)候開(kāi)始遍歷歪沃。這種方式竟然出奇的理想嗦锐,跑了82分:

/*
Team Name:happysnaker
Member 1 :qwewqewqqe:qwewqewqqe
Using default tracefiles in traces/
Perf index = 42 (util) + 40 (thru) = 82/100
*/

我們留下一個(gè)bookstr來(lái)表示上一次操作時(shí)的指針,由于我們每一次釋放空閑塊都讓這個(gè)指針指向了空閑塊沪曙,所以下一次分配時(shí)速度非常塊奕污,可以看到效率部分拿了滿分(40),但利用率卻不理想液走。

代碼:

/*
Team Name:happysnaker
Member 1 :qwewqewqqe:qwewqewqqe
Using default tracefiles in traces/
Perf index = 42 (util) + 40 (thru) = 82/100
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include "mm.h"
#include "memlib.h"
team_t team = {
    /* Team name */
    "ateam",
    /* First member's full name */
    "Harry Bovik",
    /* First member's email address */
    "bovik@cs.cmu.edu",
    /* Second member's full name (leave blank if none) */
    "",
    /* Second member's email address (leave blank if none) */
    ""
};

/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8

/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)


#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))



#define WSIZE 4
#define DSIZE 8
#define CHUNKSIZE (1 << 12)
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#define PACK(size, alloc) ((size) | (alloc))  /*設(shè)置頭部或腳部*/
#define GET(p) (*(unsigned int*)(p))
#define PUT(p, val) (*(unsigned int*)(p) = (val))
#define GET_SIZE(P) (GET(P) & ~0X7)  
#define GET_ALLOC(P) (GET(P) & 0X1)
#define HDRP(bp) ((char*)(bp) - WSIZE)  /*獲取頭部指針*/
#define FTRP(bp) ((char*)(bp) + GET_SIZE(HDRP(bp)) - DSIZE) /*根據(jù)頭部獲取腳部指針*/
#define NEXT_BLKP(bp) ((char*)(bp) + GET_SIZE(((char*)(bp) - WSIZE)))  /*下一個(gè)指向有效載荷的指針*/
#define PREV_BLKP(bp) ((char*)(bp) - GET_SIZE(((char*)(bp) - DSIZE)))
static void* extend_heap(size_t words);
static void* coalesce(void* bp);
static void *find_fit(size_t size);
static void place(void *bp,size_t asize);
static char *heap_listp = 0;
static void* bookptr;
/* 
 * mm_init - initialize the malloc package.
 */
int mm_init(void)
{
    if ((heap_listp = mem_sbrk(4 * WSIZE)) == (void*)-1)
        return -1;
    PUT(heap_listp + (1 * WSIZE), PACK(DSIZE, 1));
    PUT(heap_listp + (2 * WSIZE), PACK(DSIZE, 1));
    PUT(heap_listp + (3 * WSIZE), PACK(0, 1));
    heap_listp += (2 * WSIZE);
    bookptr = (unsigned int)heap_listp + DSIZE;  /*初始化*/
    if (extend_heap(CHUNKSIZE/WSIZE) == NULL)
        return -1;
    return 0;
}

static void* extend_heap(size_t words){
    char* bp;
    size_t size;
    size = (words % 2) ? (words + 1) * WSIZE : words * WSIZE;
    if ((long)(bp = mem_sbrk(size)) == -1)
        return NULL;
    PUT(HDRP(bp), PACK(size, 0));
    PUT(FTRP(bp), PACK(size, 0));
    PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1));
    bookptr = coalesce(bp);  /*讓它指向空閑指針*/
    return bookptr;
}

static void* coalesce(void* bp){
    size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
    size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
    size_t size = GET_SIZE(HDRP(bp));
    if (prev_alloc && next_alloc)
        return bp;
    else if (prev_alloc && !next_alloc){
        size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
        PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
        PUT(HDRP(bp), PACK(size, 0));
    }
    else if (!prev_alloc && next_alloc){
        size += GET_SIZE(HDRP(PREV_BLKP(bp)));
        PUT(FTRP(bp), PACK(size, 0));
        PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
        bp = PREV_BLKP(bp);
    }
    else{
        size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(HDRP(NEXT_BLKP(bp)));
        PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
        PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
        bp = PREV_BLKP(bp);
    }
    return bp;
}
/* 
 * mm_malloc - Allocate a block by incrementing the brk pointer.
 *     Always allocate a block whose size is a multiple of the alignment.
 */
void *mm_malloc(size_t size)
{
    char *bp;
        size_t asize;
    size_t extendsize;
    if (size <= 0)
        return NULL;
    if (size <= DSIZE)
        asize = 2 * DSIZE;
    else
        asize = DSIZE * ((size + DSIZE + (DSIZE - 1)) / DSIZE);
    if ((bp = find_fit(asize)) != NULL){
        place(bp, asize);
        bookptr = bp;
        return bp;
    }
    extendsize = MAX(asize, CHUNKSIZE);
    if ((bp = extend_heap(extendsize / WSIZE)) == NULL)
        return NULL;
    place(bp, asize);
    bookptr = bp;  /*指向上一個(gè)分配的塊*/
    return bp;
}

/*
 * mm_free - Freeing a block does nothing.
 */
void mm_free(void *ptr)
{
    size_t size = GET_SIZE(HDRP(ptr));
    PUT(HDRP(ptr), PACK(size, 0));
    PUT(FTRP(ptr), PACK(size, 0));
    bookptr = coalesce(ptr);  /*指向空閑塊*/
    return;
}

/*
 * mm_realloc - Implemented simply in terms of mm_malloc and mm_free
 */

static void *find_fit(size_t size){
    while (GET_SIZE(HDRP(bookptr)) > 0){
        if (GET_SIZE(HDRP(bookptr)) >= size && GET_ALLOC(HDRP(bookptr)) == 0)
            return bookptr;
        bookptr = NEXT_BLKP(bookptr); /*別忘了更新它*/
    }
    return NULL;
}
static void place(void *bp,size_t asize){
   size_t nowsize = GET_SIZE(HDRP(bp));
    if (nowsize - asize < 2 * DSIZE){
        PUT(HDRP(bp), PACK(nowsize, 1));
        PUT(FTRP(bp), PACK(nowsize, 1));
    }
    else{
        PUT(HDRP(bp), PACK(asize, 1));
        PUT(FTRP(bp), PACK(asize, 1));
        PUT(HDRP(NEXT_BLKP(bp)), PACK(nowsize - asize, 0));
        PUT(FTRP(NEXT_BLKP(bp)), PACK(nowsize - asize, 0));
    }
    return;
}
/*
 * mm_realloc - Implemented simply in terms of mm_malloc and mm_free
 */
void *mm_realloc(void *ptr, size_t size)
{
    size_t oldsize = GET_SIZE(HDRP(ptr));
    void* newptr = mm_malloc(size);
    if (!newptr)
        return 0;
    bookptr = newptr;  /*指向空閑塊*/
    if (!ptr)
        return newptr;
    memcpy(newptr, ptr, (size < oldsize ? size : oldsize));
    mm_free(ptr);
    return newptr;
}

隱式空閑鏈表加最佳適配

找到最小適合的塊碳默,提高利用率贾陷,這個(gè)跑分不是很理想,只有56分嘱根。代碼:
隱式空閑鏈表加最佳適配

顯式空閑鏈表加FIFO

這一次采用雙向鏈表髓废,塊的大小至少需要16字節(jié),當(dāng)前塊指針bp指向的四字節(jié)保存著上一空閑塊的指針该抒,bp + 4保存著下一空閑塊的指針慌洪。當(dāng)我們有空閑塊時(shí),我們簡(jiǎn)單的插入到根節(jié)點(diǎn)處凑保。

/*
Team Name:happysnaker
Member 1 :qwewqewqqe:qwewqewqqe
Using default tracefiles in traces/
Perf index = 45 (util) + 40 (thru) = 85/100
*/

代碼:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include "mm.h"
#include "memlib.h"

/*********************************************************
 * NOTE TO STUDENTS: Before you do anything else, please
 * provide your team information in the following struct.
 ********************************************************/
team_t team =
{
    /* Team name */
    "Xwqe",
    /* First member's full name */
    "qewqe",
    /* First member's email address */
    "sadsa",
    /* Second member's full name (leave blank if none) */
    "",
    /* Second member's email address (leave blank if none) */
    ""
};

/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8

/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)


#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))

#define WSIZE 4
#define DSIZE 8           /*Double word size*/
#define CHUNKSIZE    (1<<12) /*the page size in bytes is 4K*/
#define MAX(x,y)     ((x)>(y)?(x):(y))
#define PACK(size,alloc)    ((size) | (alloc))
#define GET(p)       (*(unsigned int *)(p))
#define PUT(p,val)   (*(unsigned int *)(p) = (val))
#define GET_SIZE(p)  (GET(p) & ~0x7)
#define GET_ALLOC(p) (GET(p) & 0x1)
#define HDRP(bp)     ((char *)(bp)-WSIZE)
#define FTRP(bp)     ((char *)(bp)+GET_SIZE(HDRP(bp))-DSIZE)
#define PREV_BLKP(bp)   ((char *)(bp)-GET_SIZE(((char *)(bp)-DSIZE)))
#define NEXT_BLKP(bp)   ((char *)(bp)+GET_SIZE(((char *)(bp)-WSIZE)))
#define NEXT_RP(bp)  ((unsigned int)(bp)+WSIZE) /*指向下一空閑塊指針*/

int mm_check(char *function);
static void *extend_heap(size_t dwords);
static void *coalesce(void *bp);
static void *find_fit(size_t size);
static void place(void *bp,size_t asize);
void __insert(char *p);
void __remove(char *p);
static char *heap_listp = NULL;
static char *root = NULL; /*這是我們的根節(jié)點(diǎn)*/

/*
 * mm_init - initialize the malloc package.
 * The return value should be -1 if there was a problem in performing the initialization, 0 otherwise
 */
int mm_init(void){
    if((heap_listp = mem_sbrk(6*WSIZE))==(void *)-1) return -1;
    PUT(heap_listp,0);
    PUT(heap_listp+(1*WSIZE),0);
    PUT(heap_listp+(2*WSIZE),0); /*內(nèi)存對(duì)齊*/
    PUT(heap_listp+(3*WSIZE),PACK(DSIZE,1));
    PUT(heap_listp+(4*WSIZE),PACK(DSIZE,1)); /*內(nèi)存對(duì)齊*/
    PUT(heap_listp+(5*WSIZE),PACK(0,1)); /*尾巴*/
    root = heap_listp + (1*WSIZE);/*初始化根節(jié)點(diǎn)*/
    heap_listp += (4*WSIZE);
    if((extend_heap(CHUNKSIZE/DSIZE)) == NULL) 
        return -1;
    return 0;
}


/*
 * mm_malloc - Allocate a block by incrementing the brk pointer.
 *     Always allocate a block whose size is a multiple of the alignment.
 */
void *mm_malloc(size_t size){
    size_t asize;
    size_t extendsize;
    char *bp;
    if(size ==0)
     return NULL;
    if(size <= DSIZE)
        asize = 2*(DSIZE);
    else
        asize = (DSIZE) * ((size + DSIZE + (DSIZE-1)) / (DSIZE));
    if((bp = find_fit(asize))!= NULL){
        place(bp,asize);
        return bp;
    }

    extendsize = MAX(asize,CHUNKSIZE);
    if((bp = extend_heap(extendsize/DSIZE))==NULL)
        return NULL;
    place(bp,asize);
    return bp;
}

/*
 * mm_free - Freeing a block does nothing.
 */
void mm_free(void *bp){
    if(bp == NULL)
        return;
    size_t size = GET_SIZE(HDRP(bp));
    PUT(HDRP(bp), PACK(size, 0));
    PUT(FTRP(bp), PACK(size, 0));
    PUT(NEXT_RP(bp),0); /*剛釋放的塊冈爹,設(shè)置前后指針為null*/
    PUT(bp,0);
    coalesce(bp);
}
/*
 * mm_realloc - Implemented simply in terms of mm_malloc and mm_free
 */
void *mm_realloc(void *ptr, size_t size){
    
    void *newptr = mm_malloc(size);
    if(!newptr){
        return 0;
    }
    if(ptr == NULL){
        return newptr;
    }

    size_t oldsize = GET_SIZE(HDRP(ptr));
    memcpy(newptr, ptr, oldsize < size ? oldsize : size);
    mm_free(ptr);

    return newptr;
}
static void *find_fit(size_t size){
    /*first fit*/
    char *bp = GET(root);
    while(bp != NULL){
        if(GET_SIZE(HDRP(bp)) >= size) 
            return bp;  
        bp = GET(NEXT_RP(bp));
    }
    return NULL;

}

static void place(void *bp,size_t asize)
{
    size_t csize = GET_SIZE(HDRP(bp));
    __remove(bp);   /*使用了這個(gè)塊,切記移除它*/
    if(csize-asize >= 2 *DSIZE){
        PUT(HDRP(bp),PACK(asize,1));
        PUT(FTRP(bp),PACK(asize,1));
        PUT(HDRP(NEXT_BLKP(bp)),PACK(csize-asize,0));
        PUT(FTRP(NEXT_BLKP(bp)),PACK(csize-asize,0));
        PUT(NEXT_RP(bp),0);
        PUT((NEXT_BLKP(bp)),0);
        coalesce(NEXT_BLKP(bp));
    }
    else{
        PUT(HDRP(bp),PACK(csize,1));
        PUT(FTRP(bp),PACK(csize,1));
    }
}

static void *extend_heap(size_t words)
{
    char *bp;
    size_t size;
    size = (words % 2) ? (words+1) * DSIZE : words * DSIZE;
    if((long)(bp = mem_sbrk(size))==(void *)-1)
        return NULL;
    PUT(HDRP(bp),PACK(size,0));
    PUT(FTRP(bp),PACK(size,0));
    PUT(HDRP(NEXT_BLKP(bp)),PACK(0,1));
    PUT(NEXT_RP(bp),0);
    PUT(bp,0);
    return coalesce(bp);
}

/*coalesce the empty block*/
static void *coalesce(void *bp)
{
    size_t  prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
    size_t  next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
    size_t size = GET_SIZE(HDRP(bp));

    /*coalesce the block and change the point*/
    if(prev_alloc && !next_alloc){
        size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
        __remove(NEXT_BLKP(bp)); /*使用了這個(gè)塊欧引,切記移除它*/
        PUT(HDRP(bp), PACK(size,0));
        PUT(FTRP(bp), PACK(size,0));
    }
    else if(!prev_alloc && next_alloc){
        size += GET_SIZE(HDRP(PREV_BLKP(bp)));
        __remove(PREV_BLKP(bp));/*使用了這個(gè)塊频伤,切記移除它*/
        PUT(FTRP(bp),PACK(size,0));
        PUT(HDRP(PREV_BLKP(bp)),PACK(size,0));
        bp = PREV_BLKP(bp);
    }
    else if (!prev_alloc && !next_alloc){
        size +=GET_SIZE(FTRP(NEXT_BLKP(bp)))+ GET_SIZE(HDRP(PREV_BLKP(bp)));
        __remove(PREV_BLKP(bp));/*使用了這個(gè)塊,切記移除它*/
        __remove(NEXT_BLKP(bp));/*使用了這個(gè)塊芝此,切記移除它*/
        PUT(FTRP(NEXT_BLKP(bp)),PACK(size,0));
        PUT(HDRP(PREV_BLKP(bp)),PACK(size,0));
        bp = PREV_BLKP(bp);
    }
    __insert(bp);/*新的空閑塊憋肖,記住插入*/
    return bp;
}
inline void __insert(char *bp)
{
    //PUT(bp, root); 這個(gè)操作有段錯(cuò)誤,挺離譜的
    char *next = GET(root);
    if(next != NULL)
        PUT(next, bp);
    PUT(NEXT_RP(bp), next);
    PUT(root,bp);
}
inline void __remove(char *bp){
    char *pre = GET((bp));
    char *next = GET(NEXT_RP(bp));
    /*因?yàn)樯厦娌迦氩僮鞑荒苤胋p的前驅(qū)為root,所以這個(gè)是必須考慮的婚苹,這個(gè)代表前面就是根節(jié)點(diǎn)了 */
    if(pre == NULL){
        if(next != NULL)
            PUT(next,0);
        PUT(root,next);
    }
    else{
        if(next != NULL)
            PUT((next),pre);
        PUT(NEXT_RP(pre),next);
    }
    PUT(NEXT_RP(bp),0);
    PUT(bp,0);
}


插入操作設(shè)置前驅(qū)為root竟然有段錯(cuò)誤瞬哼,真是折殺我也,也許是因?yàn)椴唤?jīng)意間會(huì)訪問(wèn)NEXT_RP(root)吧租副,這個(gè)值被我們?cè)O(shè)置成了NULL坐慰。哎,由衷敬佩操作系統(tǒng)開(kāi)發(fā)者用僧,和內(nèi)存打交道太不容易了结胀。

其實(shí)這個(gè)在插入時(shí)我覺(jué)得還可以以升序的方式插入,這樣可以提高利用率责循≡愀郏可惜了,還是我們的老朋友段錯(cuò)誤院仿,哎秸抚。

看來(lái)想要滿績(jī)(90)必須要采用分離適配了,最近被段錯(cuò)誤弄的有點(diǎn)暈歹垫,不過(guò)立個(gè)flag剥汤,2021年一定要完成它!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末排惨,一起剝皮案震驚了整個(gè)濱河市吭敢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌暮芭,老刑警劉巖鹿驼,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欲低,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡畜晰,警方通過(guò)查閱死者的電腦和手機(jī)砾莱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)凄鼻,“玉大人腊瑟,你說(shuō)我怎么就攤上這事∫耙耍” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵魔策,是天一觀的道長(zhǎng)匈子。 經(jīng)常有香客問(wèn)我,道長(zhǎng)闯袒,這世上最難降的妖魔是什么虎敦? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮政敢,結(jié)果婚禮上其徙,老公的妹妹穿的比我還像新娘。我一直安慰自己喷户,他們只是感情好唾那,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著褪尝,像睡著了一般闹获。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上河哑,一...
    開(kāi)封第一講書(shū)人閱讀 50,021評(píng)論 1 291
  • 那天避诽,我揣著相機(jī)與錄音,去河邊找鬼璃谨。 笑死沙庐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的佳吞。 我是一名探鬼主播拱雏,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼底扳!你這毒婦竟也來(lái)了古涧?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤花盐,失蹤者是張志新(化名)和其女友劉穎羡滑,沒(méi)想到半個(gè)月后菇爪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柒昏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年凳宙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片职祷。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡氏涩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出有梆,到底是詐尸還是另有隱情是尖,我是刑警寧澤,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布泥耀,位于F島的核電站饺汹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏痰催。R本人自食惡果不足惜兜辞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望夸溶。 院中可真熱鬧逸吵,春花似錦、人聲如沸缝裁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捷绑。三九已至啸罢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胎食,已是汗流浹背扰才。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厕怜,地道東北人衩匣。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像粥航,于是被迫代替她去往敵國(guó)和親琅捏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350

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