通过零长度的数组获取结构体大小
生活随笔
收集整理的這篇文章主要介紹了
通过零长度的数组获取结构体大小
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
為什么80%的碼農都做不了架構師?>>> ??
mysize.c
#include <stdio.h> #include <stdlib.h>struct S {int a;double b;char s[0]; };int main(int argc, char *argv[]) {struct S *size = NULL;printf("%d\n", size->s);printf("sizeof(struct S) = %d\n", sizeof(struct S));return 0; }輸出:
16 sizeof(struct S) = 16gdb 調試信息
### BEGIN LOG - DATE: 170616, TIME: 195749 ###gdb ./mysize GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-suse-linux"... Using host libthread_db library "/lib64/libthread_db.so.1". (gdb) l 3 4 struct S { 5 int a; 6 double b; 7 char s[0]; 8 }; 9 10 int main(int argc, char *argv[]) 11 { 12 struct S *size = NULL; (gdb) l 13 printf("%d\n", size->s); 14 15 printf("sizeof(struct S) = %d\n", sizeof(struct S)); 16 return 0; 17 } (gdb) b 12 Breakpoint 1 at 0x400507: file mysize.c, line 12. (gdb) r Starting program: /data/home/shenhontang/test/tsh_code/mysize/mysize Failed to read a valid object file image from memory. [Thread debugging using libthread_db enabled] [New Thread 139774018967248 (LWP 4527)] [Switching to Thread 139774018967248 (LWP 4527)]Breakpoint 1, main (argc=1, argv=0x7fff69e43f28) at mysize.c:12 12 struct S *size = NULL; (gdb) s 13 printf("%d\n", size->s); (gdb) p size $1 = (struct S *) 0x0 (gdb) p size->a Cannot access memory at address 0x0 (gdb) p size->b Cannot access memory at address 0x8 (gdb) p size->s $2 = 0x10 <Address 0x10 out of bounds> (gdb) s 16 15 printf("sizeof(struct S) = %d\n", sizeof(struct S)); (gdb) s sizeof(struct S) = 16 16 return 0; (gdb) s 17 } (gdb) quit The program is running. Exit anyway? (y or n) y### END LOG - DATE: 170616, TIME: 200119 ###系統為 64bit linux 系統
指針和數組的差別有了上面的基礎后,你把源代碼中的struct str結構體中的char s[0];改成char *s;試試看,你會發現,在13行if條件的時候,程序因為Cannot access memory就直接掛掉了。為什么聲明成char s[0],程序會在14行掛掉,而聲明成char *s,程序會在13行掛掉呢?那么char *s 和 char s[0]有什么差別呢?在說明這個事之前,有必要看一下匯編代碼,用GDB查看后發現:?對于char s[0]來說,匯編代碼用了lea指令,lea 0x04(%rax), %rdx?對于char*s來說,匯編代碼用了mov指令,mov 0x04(%rax), %rdxlea全稱load effective address,是把地址放進去,而mov則是把地址里的內容放進去。所以,就crash了。從這里,我們可以看到,訪問成員數組名其實得到的是數組的相對地址,而訪問成員指針其實是相對地址里的內容(這和訪問其它非指針或數組的變量是一樣的)換句話說,對于數組 char s[10]來說,數組名 s 和 &s 都是一樣的(不信你可以自己寫個程序試試)。參考:?http://coolshell.cn/articles/11377.html
轉載于:https://my.oschina.net/tsh/blog/974033
總結
以上是生活随笔為你收集整理的通过零长度的数组获取结构体大小的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS逆向之iOSOpenDev
- 下一篇: 虚拟化VMware之存储与虚拟机主机管理