帶你深入理解iOS-內(nèi)存對(duì)齊

前言

  • 在iOS底層源碼學(xué)習(xí)中劲赠,會(huì)需要分析一個(gè)結(jié)構(gòu)體所占用的內(nèi)存大小,這里面就涉及到了內(nèi)存對(duì)齊
  • 今天秸谢,我將結(jié)合內(nèi)存對(duì)齊的概念凛澎、原因、規(guī)則估蹄、實(shí)際例子塑煎,讓你深入理解內(nèi)存對(duì)齊,掌握分析結(jié)構(gòu)體所占內(nèi)存大小的方法臭蚁。
    目錄.png
源碼地址

MemoryAlignment

簡(jiǎn)介

內(nèi)存對(duì)齊”應(yīng)該是編譯器的“管轄范圍”最铁。編譯器為程序中的每個(gè)“數(shù)據(jù)單元”安排在適當(dāng)?shù)奈恢蒙稀H绻阆肓私飧拥讓拥拿孛芸宥遥骄俊皟?nèi)存對(duì)齊”對(duì)你就不應(yīng)該再模糊了冷尉。

  • 平臺(tái)原因(移植原因):不是所有的硬件平臺(tái)都能訪問任意地址上的任意數(shù)據(jù)的;某些硬件平臺(tái)只能在某些地址處取某些特定類型的數(shù)據(jù)甥角,否則拋出硬件異常网严。
  • 性能原因:數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對(duì)齊。原因在于嗤无,為了訪問未對(duì)齊的內(nèi)存震束,處理器需要作兩次內(nèi)存訪問;而對(duì)齊的內(nèi)存訪問僅需要一次訪問当犯。

特別對(duì)于我們學(xué)習(xí)底層源碼垢村,是需要掌握的知識(shí)點(diǎn)之一,下面我就結(jié)合百度百科-內(nèi)存對(duì)齊以及實(shí)際的demo進(jìn)行詳細(xì)分析嚎卫。

1嘉栓、規(guī)則定義

  • 規(guī)則1、數(shù)據(jù)成員對(duì)齊規(guī)則:結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員拓诸,第一個(gè)數(shù)據(jù)成員放在offset為0的地方侵佃,以后每個(gè)數(shù)據(jù)成員的對(duì)齊,按照#pragma pack指定的數(shù)值和這個(gè)數(shù)據(jù)成員自身長(zhǎng)度中奠支,比較小的那個(gè)進(jìn)行馋辈。

  • 規(guī)則2、結(jié)構(gòu)(或聯(lián)合)的整體對(duì)齊規(guī)則:在數(shù)據(jù)成員完成各自對(duì)齊之后倍谜,結(jié)構(gòu)(或聯(lián)合)本身也要進(jìn)行對(duì)齊迈螟,對(duì)齊將按照#pragma pack指定的數(shù)值和結(jié)構(gòu)(或聯(lián)合)最大數(shù)據(jù)成員長(zhǎng)度中叉抡,比較小的那個(gè)進(jìn)行

  • 規(guī)則3答毫、結(jié)合1褥民、2可推斷:當(dāng)#pragma pack的n值等于或超過所有數(shù)據(jù)成員長(zhǎng)度的時(shí)候,這個(gè)n值的大小將不產(chǎn)生任何效果洗搂。

2消返、規(guī)則解析

  • 規(guī)則1中表明數(shù)據(jù)成員的存放是按照定義的順序依次存放的
  • #pragma pack是對(duì)齊系數(shù),每個(gè)平臺(tái)不一樣蚕脏,程序員可以通過預(yù)編譯命令#pragma pack(n)侦副,n=1,2,4,8,16來改變這一系數(shù)(32位平臺(tái)一般為4,64位平臺(tái)一般為8)驼鞭。iOS下默認(rèn)為8。這個(gè)數(shù)值大家可以通過調(diào)試#pragma pack(n)測(cè)試驗(yàn)證得到尺碰。
  • 規(guī)則1挣棕,當(dāng)?shù)趚(x>1)個(gè)成員y存放的時(shí)候,y按照min(n,m)來對(duì)齊存放亲桥,其中n為對(duì)齊系數(shù)洛心,m為成員y的數(shù)據(jù)類型長(zhǎng)度。
  • 在完成各個(gè)數(shù)據(jù)成員的存放排列后题篷,通過規(guī)則2词身,取min(n,maxM)進(jìn)行對(duì)齊,其中n為對(duì)齊系數(shù)番枚,maxM為所有數(shù)據(jù)成員類型中長(zhǎng)度的最大值法严。

3、實(shí)例分析

demo例子中我們定義具有相同類型和個(gè)數(shù)成員的結(jié)構(gòu)體葫笼,但是其定義的順序不同成員不同深啤,并對(duì)其進(jìn)行賦值,然后結(jié)合規(guī)則路星,詳細(xì)進(jìn)行分析溯街。

基礎(chǔ)知識(shí)點(diǎn)介紹

1.一個(gè)字節(jié)包含8個(gè)二進(jìn)制位
2.一個(gè)十六進(jìn)制位可用4個(gè)二進(jìn)制位表示
3.一個(gè)字節(jié)可以由2個(gè)十六進(jìn)制位表示
0x0000 0000 0000 0008表示16個(gè)16進(jìn)制位,可以表示8個(gè)字節(jié)
所以8可以用8個(gè)字節(jié)0x0000 0000 0000 0008表示洋丐,或者4個(gè)字節(jié)0x0000 0008呈昔,或者2個(gè)字節(jié)0x0008,取決于定義8的數(shù)據(jù)類型友绝。
字符'a'換成ASCII碼為97堤尾,可以用 0x61表示。
此外九榔,iOS系統(tǒng)的編譯平臺(tái)是按照小端法進(jìn)行編譯哀峻。

下面進(jìn)入具體的實(shí)例分析涡相,
環(huán)境:
Xcode 11.3.1,Deployment Target:10.15
代碼如下:
CommandLineTool類型工程的main.m文件中


#import <Foundation/Foundation.h>

struct Person1 {
    char a;
    long b;
    int c;
    short d;
}MyPerson1;

struct Person2 {
    long b;
    char a;
    int c;
    short d;
}MyPerson2;

struct Person3 {
    long b;
    int c;
    char a;
    short d;
}MyPerson3;

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        MyPerson1.a = 'a';
        MyPerson1.b = 8;
        MyPerson1.c = 4;
        MyPerson1.d = 2;
        
        MyPerson2.b = 18;
        MyPerson2.a = 'a';
        MyPerson2.c = 14;
        MyPerson2.d = 12;
        
        MyPerson3.b = 28;
        MyPerson3.c = 24;
        MyPerson3.a = 'a';
        MyPerson3.d = 22;
        NSLog(@"Adress=======MyPerson1:%p,MyPerson2:%p,MyPerson3:%p",&MyPerson1,&MyPerson2,&MyPerson3);  
        NSLog(@"Size=======MyPerson1:%lu,MyPerson2:%lu,MyPerson3:%lu",sizeof(MyPerson1),sizeof(MyPerson2),sizeof(MyPerson3));

    }
    return 0;
}

分析MyPerson1

struct Person1 {
    char a;
    long b;
    int c;
    short d;
}MyPerson1;
  • 第一個(gè)成員char類型的成員a='a'占用1字節(jié),此時(shí):
    a: 0x61

  • 第二個(gè)成員long類型的成員b=8占用8個(gè)字節(jié)剩蟀,根據(jù)規(guī)則解析3催蝗,b=8按照min(8,8)=8對(duì)齊,b的起始位置為8的倍數(shù)育特,不滿足丙号,a需要補(bǔ)齊7個(gè)字節(jié)保證b的起始位置為8的倍數(shù)
    此時(shí):
    a:0x0000 0000 0000 0061
    b:0x0000 0000 0000 0008

  • 第三個(gè)成員int類型的成員c=4占用4個(gè)字節(jié),根據(jù)規(guī)則解析3,整數(shù)c=4需要按照min(8,4)=4進(jìn)行對(duì)齊缰冤,c的起始位置需要為4的整數(shù)倍犬缨,現(xiàn)在已經(jīng)滿足
    此時(shí):
    a:0x0000 0000 0000 0061
    b:0x0000 0000 0000 0008
    c:0x0000 0004

  • 第四個(gè)成員short類型的整數(shù)d=2占用2個(gè)字節(jié),根據(jù)規(guī)則解析3棉浸,d按照min(8,2)=2進(jìn)行對(duì)齊怀薛,d的起始位置需要為2的整數(shù)倍,現(xiàn)在已經(jīng)滿足
    此時(shí):
    a:0x0000 0000 0000 0061
    b:0x0000 0000 0000 0008
    c:0x0000 0004
    d:0x0002

  • 根據(jù)規(guī)則解析4迷郑,結(jié)構(gòu)體需要進(jìn)行整體對(duì)齊枝恋,取min(n,maxDataLength) = max(8,8) = 8對(duì)齊,現(xiàn)在為8+8+4+2=22字節(jié)嗡害,需要補(bǔ)2個(gè)字節(jié)焚碌,按照排列順序,在d占用內(nèi)存段補(bǔ)2個(gè)字節(jié);

  • 最后得到
    a:0x0000 0000 0000 0061
    b:0x0000 0000 0000 0008
    c:0x0000 0004
    d:0000 0002
    其中我們看把c和d看成共占用一段8字節(jié)的內(nèi)存霸妹,因?yàn)閷?duì)齊系數(shù)為8十电,編譯器按照8的整數(shù)倍來讀取內(nèi)存地址

  • 按照小端法進(jìn)行修正叹螟,此時(shí)內(nèi)存排列應(yīng)該內(nèi)應(yīng)該是
    a:0x0000 0000 0000 0061
    b:0x0000 0000 0000 0008
    dc:0x0000 0002 0000 0004
    鹃骂,
    其中dc:0x0000 0002 0000 0004的第1-8位表示成員d的值,右邊第9-16位表示成員c的值

  • 綜上,MyPerson1結(jié)構(gòu)體整體占用8+8+8=24字節(jié)

分析MyPerson2

struct Person2 {
    long b;
    char a;
    int c;
    short d;
}MyPerson2;

  • 第一個(gè)成員long類型的成員b=18占用8字節(jié)首妖,此時(shí):
    b:0x0000 0000 0000 0012

  • 第二個(gè)成員char類型的成員a='b'占用1個(gè)字節(jié)偎漫,根據(jù)規(guī)則解析3,a按照min(8,1)=1對(duì)齊有缆,a的起始位置需要為1的整數(shù)倍象踊,已經(jīng)滿足,此時(shí):
    b:0x0000 0000 0000 0012
    a:0x62

  • 第三個(gè)成員int類型的成員c=14占用4個(gè)字節(jié),根據(jù)規(guī)則解析3棚壁,c按照min(8,4)=4進(jìn)行對(duì)齊杯矩,c的起始位置需要未4的整數(shù)倍,不滿足袖外,所以成員a='b'需要補(bǔ)齊3個(gè)字節(jié)史隆, 此時(shí):
    b:0x0000 0000 0000 0012
    a:0x0000 0062
    c:0x0000 000e

  • 第四個(gè)成員short類型的成員d=12占用2個(gè)字節(jié),根據(jù)規(guī)則解析3曼验,成員d按照min(8,2)=2進(jìn)行對(duì)齊,起始位置需要為2的整數(shù)倍泌射,已經(jīng)滿足粘姜,此時(shí) :
    b:0x0000 0000 0000 0012
    a:0x0000 0062
    c:0x0000 000e
    d:000c

  • 根據(jù)規(guī)則解析4,結(jié)構(gòu)體需要進(jìn)行整體對(duì)齊熔酷,取min(n,maxDataLength) = max(8,8) = 8對(duì)齊孤紧, 現(xiàn)在占用8+4+4+2=18個(gè)字節(jié),需要補(bǔ)6個(gè)字節(jié)拒秘,按照排列順序号显,在d占用的內(nèi)存段補(bǔ)6個(gè)字節(jié)

  • 最后得到 :
    b:0x0000 0000 0000 0012
    a:0x0000 0062
    c:0x0000 000e
    d:0000 0000 0000 000c,其中我們看把a(bǔ)躺酒、c看成共占用一段8字節(jié)的內(nèi)存押蚤,因?yàn)閷?duì)齊系數(shù)為8,編譯器按照8的整數(shù)倍來讀取內(nèi)存地址

  • 按照小端法修正羹应,此時(shí)真正的內(nèi)存排列應(yīng)該內(nèi)應(yīng)該是:
    b:0x0000 0000 0000 0012
    ca:0x0000 000e 0000 0062
    d:0x0000 0000 0000 000c 揽碘,

    其中ca:0x0x0000 000e 0000 0062 的第1-8位表示c的值,第9-16表示a的值

  • 綜上园匹,MyPerson2整體占用8+8+8=24個(gè)字節(jié)

分析MyPerson3

struct Person3 {
    long b;
    int c;
    char a;
    short d;
}MyPerson3;
  • 第一個(gè)成員long類型的成員b=28占用8字節(jié)钾菊,此時(shí):
    b:0x0000 0000 0000 001c

  • 第二個(gè)成員int類型的成員c=24占用4個(gè)字節(jié),根據(jù)規(guī)則1, 成員c按min(8,4)=4對(duì)齊偎肃,c的起始位置需要為4的整數(shù)倍,已經(jīng)滿足浑此,此時(shí):
    b:0x0000 0000 0000 001c
    c:0x0000 0018

  • 第三個(gè)成員char類型的成員a='c'占用1個(gè)字節(jié),根據(jù)規(guī)則1累颂,成員a按min(8,1)=1進(jìn)行對(duì)齊此時(shí):
    b:0x0000 0000 0000 001c
    c:0x0000 0018
    a:0x63

  • 第四個(gè)成員short類型的成員d=22占用2個(gè)字節(jié),根據(jù)規(guī)則1凛俱,成員d按照min(8,2)=2進(jìn)行對(duì)齊,d的起始位置需要為2的整數(shù)倍紊馏,因此成員a需要補(bǔ)1字節(jié),此時(shí):
    b:0x0000 0000 0000 001c
    c:0x0000 0018
    a:0x0063
    d:0x0016

  • 根據(jù)規(guī)則解析4蒲犬,結(jié)構(gòu)體需要進(jìn)行整體對(duì)齊朱监,取min(n,maxDataLength) = max(8,8) = 8對(duì)齊,但是現(xiàn)在占用8+4+2+2=16個(gè)字節(jié)原叮,已經(jīng)滿足了

  • 最后得到:
    b:0x0000 0000 0000 001c
    c:0x0000 0018
    a:0063
    d:0016赫编,其中我們看把c、a奋隶、d看成共占用一段8字節(jié)的內(nèi)存擂送,因?yàn)閷?duì)齊系數(shù)為8,編譯器按照8的整數(shù)倍來讀取內(nèi)存地址

  • 按照小端法修正唯欣,此時(shí)真正的內(nèi)存排列應(yīng)該內(nèi)應(yīng)該是 最后得到
    b:0x0000 0000 0000 001c
    dac:0x0016 0063 0000 0018
    ,其中dac:0x0016 0063 0000 0018的左邊第1-4位表示d存儲(chǔ)的值嘹吨,左邊第5-8位表示a存儲(chǔ)的值,右邊第9-16位表示c存儲(chǔ)的值
    綜上境氢,MyPerson3結(jié)構(gòu)體整體占用8+8=16個(gè)字節(jié)

驗(yàn)證

如圖輸出結(jié)構(gòu)體成員信息


lldb輸出.png
  • 我們把各個(gè)結(jié)構(gòu)體的地址打印出來蟀拷,然后利用lldb的x/4gx命令輸出各個(gè)結(jié)構(gòu)體里面的從第一個(gè)成員的起始位置開始的4段8字節(jié)內(nèi)存信息
  • x/4gx 0x100002020表示打印從MyPerson1的成員a='a'開始的4段內(nèi)存信息碰纬,其中前3段 0x0000000000000061 0x0000000000000008,0x0000000200000004和我們前面分析的MyPerson1得出的內(nèi)存表示一致问芬,最后一段0x0000000000000012不屬于MyPerson1悦析,代表MyPerson2的成員b=18內(nèi)存表示
  • x/4gx 0x100002038表示打印從MyPerson2的成員b=18開始的4段內(nèi)存信息,其中前3段 0x0000000000000012愈诚,0x0000000e00000062, 0x000000000000000c和我們前面分析的MyPerson2得出的內(nèi)存表示一致她按,最后一段0x000000000000001c不屬于MyPerson2,代表MyPerson3的成員b=28的內(nèi)存表示
  • x/4gx 0x100002050 表示打印從MyPerson3的成員b=28開始的4段內(nèi)存信息炕柔,其中前2段 0x000000000000001c酌泰,0x0016006300000018和我們前面分析的MyPerson2得出的內(nèi)存表示一致,后面2段0x0000000000000000不屬于MyPerson3

優(yōu)化lldb的打印輸出如下

優(yōu)化輸出
  • 通過優(yōu)化輸出可以看到lldb輸出的內(nèi)存表示與我們前面實(shí)例分析的是一致匕累。

OC對(duì)象分析

仿照上面的3個(gè)結(jié)構(gòu)體定義3個(gè)類Teacher1,Teacher2,Teacher3

@interface Teacher1 : NSObject

@property (nonatomic, assign) char a;
@property (nonatomic, assign) long b;
@property (nonatomic, assign) int c;
@property (nonatomic, assign) short d;

@end
@interface Teacher2 : NSObject

@property (nonatomic, assign) long b;
@property (nonatomic, assign) char a;
@property (nonatomic, assign) int c;
@property (nonatomic, assign) short d;

@end
@interface Teacher3 : NSObject

@property (nonatomic, assign) int c;
@property (nonatomic, assign) long b;
@property (nonatomic, assign) char a;
@property (nonatomic, assign) short d;

@end

main.m中添加如下代碼

        Teacher1 *t1 = [[Teacher1 alloc] init];
        t1.a = 'a';
        t1.b = 8;
        t1.c = 4;
        t1.d = 2;
        
        Teacher2 *t2 = [[Teacher2 alloc] init];
        t2.b = 18;
        t2.a = 'b';
        t2.c = 14;
        t2.d = 12;
        
        Teacher3 *t3 = [[Teacher3 alloc] init];
        t3.b = 28;
        t3.c = 24;
        t3.a = 'c';
        t3.d = 22;
對(duì)象的輸出如下
image.png
  • 可以看到陵刹,3個(gè)對(duì)象的第2個(gè)八字節(jié)和第三個(gè)八字節(jié)這2個(gè)內(nèi)存段存儲(chǔ)了我們定義的成員a、b欢嘿、c衰琐、d(準(zhǔn)確表述為_a,_b炼蹦,_c羡宙,_d)的值,說明編譯器做了相應(yīng)的優(yōu)化掐隐,不會(huì)直接按照我們?cè)陬愔卸x成員的順序生成構(gòu)造對(duì)應(yīng)的結(jié)構(gòu)體
  • 3個(gè)對(duì)象的第一個(gè)八字節(jié)存儲(chǔ)著各自isa的值
  • 如果定義有float或者double類型的成員狗热,比如Teacher1
@interface Teacher1 : NSObject

@property (nonatomic, assign) double height;

@end

Teacher1 *t1 = [[Teacher1 alloc] init];
t1.height = 175;

由于float和double的位表示是經(jīng)過一定算法得到,無法直接通過簡(jiǎn)單手工計(jì)算得出虑省,可以使用lldb命令:p/x (double)175得到的其位表示匿刮,再與x/4gx t1中的進(jìn)行對(duì)比。

4探颈、思考

下面代碼輸出什么熟丸?

NSLog(@"sizeof=======t1:%lu,t2:%lu,t3:%lu",sizeof(t1),sizeof(t2),sizeof(t3));
NSLog(@"class_getInstanceSize=======t1:%lu,t2:%lu,t3:%lu",class_getInstanceSize(t1.class),class_getInstanceSize(t2.class),class_getInstanceSize(t3.class));
NSLog(@"malloc_size=======t1:%lu,t2:%lu,t3:%lu",malloc_size((__bridge const void*)t1),malloc_size((__bridge const void*)t2),malloc_size((__bridge const void*)t3));

輸出如下:

sizeof=======t1:8,t2:8,t3:8
class_getInstanceSize=======t1:24,t2:24,t3:24
malloc_size=======t1:32,t2:32,t3:32
  • sizeof計(jì)算的是傳入?yún)?shù)的類型所占字節(jié)大小。t1為Teacher1 *類型伪节,本質(zhì)上是一個(gè)objc_objct的結(jié)構(gòu)體指針光羞,所以占8字節(jié),t2架馋、t3同理狞山。
  • class_getInstanceSize輸出的是對(duì)象實(shí)例經(jīng)過內(nèi)存對(duì)齊后的占用的大小。前面通過分析叉寂,t1所占大小應(yīng)該為16字節(jié)萍启,但是t1本質(zhì)上是一個(gè)objc_objct的結(jié)構(gòu)體指針,objc_objct結(jié)構(gòu)體內(nèi)部還有一個(gè)占8字節(jié)的isa_t,即我們通過lldb調(diào)試x/4gx輸出的第一段內(nèi)存,因此為8+16=24字節(jié)勘纯,t2局服、t3同理。
  • malloc_size返回的是指針?biāo)赶虻膬?nèi)存空間所占的大小驳遵,即系統(tǒng)實(shí)際分配的大小淫奔。其值為class_getInstanceSize的值按16字節(jié)對(duì)齊得到,因此為32字節(jié)堤结。

關(guān)于class_getInstanceSize唆迁、malloc_size的詳解參考《OC底層系列二》-對(duì)象中的class_getInstanceSize以及malloc_size部分。

總結(jié)

  • 本文主要對(duì)內(nèi)存對(duì)齊的規(guī)則進(jìn)行介紹和并結(jié)合實(shí)際的demo例子對(duì)結(jié)構(gòu)體和對(duì)象進(jìn)行詳細(xì)分析
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末竞穷,一起剝皮案震驚了整個(gè)濱河市唐责,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘾带,老刑警劉巖鼠哥,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異看政,居然都是意外死亡朴恳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門允蚣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來于颖,“玉大人,你說我怎么就攤上這事嚷兔』衅” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵谴垫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我母蛛,道長(zhǎng)翩剪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任彩郊,我火速辦了婚禮前弯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秫逝。我一直安慰自己恕出,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布违帆。 她就那樣靜靜地躺著浙巫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上的畴,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天渊抄,我揣著相機(jī)與錄音,去河邊找鬼丧裁。 笑死护桦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的煎娇。 我是一名探鬼主播二庵,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼缓呛!你這毒婦竟也來了催享?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤强经,失蹤者是張志新(化名)和其女友劉穎睡陪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匿情,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兰迫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了炬称。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汁果。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖玲躯,靈堂內(nèi)的尸體忽然破棺而出据德,到底是詐尸還是另有隱情,我是刑警寧澤跷车,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布棘利,位于F島的核電站,受9級(jí)特大地震影響朽缴,放射性物質(zhì)發(fā)生泄漏善玫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一密强、第九天 我趴在偏房一處隱蔽的房頂上張望茅郎。 院中可真熱鬧,春花似錦或渤、人聲如沸系冗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)掌敬。三九已至惯豆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涝开,已是汗流浹背循帐。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舀武,地道東北人拄养。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像银舱,于是被迫代替她去往敵國(guó)和親瘪匿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359