.
.
.
.
.
LZ 今天在寫一個 Socket 程序的時候使用 malloc(3) 在堆上動態分配了一個結構體的空間,在使用完之后用 free(3) 函數釋放空間的時候報 invalid next size 這樣的一個錯誤,經過了兩個小時的調試,最后發現是因為粗心越界導致的。
LZ 把這個錯誤縮減為一個最簡單的模型發布出來:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int main (void) 6 { 7 char *p = NULL; 8 9 // 在堆空間申請 8 字節的內存 10 p = malloc(8); 11 12 // 實際使用超過 8 字節 13 strncpy(p, "abcd", 128); 14 // 可以正常打印 15 printf("p = %s\n", p); 16 17 // 釋放內存時會報 invalid next size 錯誤 18 free(p); 19 20 return 0; 21 }
編譯運行:
>$ gcc -Wall free.c -o free >$ ./free p = abcdefghijklmn *** glibc detected *** ./free: free(): invalid next size (fast): 0x00000000020c3010 *** ...此處生略 n 行...
打印是不受影響的,但其實在 strncpy(3) 的時候就已經越界了,所以發生什么情況都是正常的。
另外對於上面這個栗子,使用 strcpy(3) 替代 strncpy(2) 就不會報錯了,但是一旦要拷貝的字符超過了 8 個字節,依然可能引發錯誤。
所以大家在使用內存的時候一定要注意長度,千萬不可越界。