發表文章

目前顯示的是 三月, 2013的文章

mmap

下面是一個很簡單、很一般的程式碼,內容是使用 openssl 所提供的函式去計算一個檔案的 MD5。既然這麼簡單為什麼要紀錄呢?理由有兩個:第一,紀錄一下要怎麼使用 openssl 的 library;第二是今天的重點,mmap。 一般來說,要計算一個檔案的 MD5,勢必要把整個檔案讀到記憶體當中(或是分批讀入,但勢必整個檔案都要吃進來),所以標準的程序應該是 open --> read --> md5 --> close。而在 read 這一步還需要額外準備一份記憶體空間給它。但如果使用 mmap 的話就可以直接少了 read 這一步了。 # include <stdio.h> # include <stdlib.h> # include <string.h> # include <unistd.h> # include <fcntl.h> # include <sys/mman.h> # include <sys/types.h> # include <sys/stat.h> # include <openssl/md5.h> long util_getFileSize ( char * ); void util_md5File ( char *, unsigned char * ); static long util_getFdSize ( int ); int main ( int argc, char *argv[] ) { int fileFd = 0; long fileSize = 0; unsigned char md5sum[MD5_DIGEST_LENGTH]; int i = 0; if( argc != 2 ) { printf( "Usage: md5 <file>\n" ); return 0; }

memcpy vs. memmove

這個事件是在工作中時間發生的案例。先看看下面的例子: # include < stdio.h > # include < stdlib.h > # include < string.h > int main () { int a[100]; int i = 0; int index = 5; for ( i = 0 ; i < 100 ; i++ ) { a[i] = i; } memcpy ( &(a[index]), &(a[(index + 1)]), sizeof ( int ) * ( 100 - index - 1 ) ); for ( i = 0 ; i < 100 ; i++ ) { printf ( " %d " , a[i] ); if ( ( i % 10 ) == 9 ) { printf ( " \n " ); } } printf ( " \n " ); return 0; } 好了,請問上面這段程式碼在寫什麼呢? 其實很簡單,這只是一個 array shift 的動作,將 index 後面的元素全部往前搬動一格。這樣寫會有什麼問題呢?我在我自己的電腦上什麼問題都沒有發生啊? 邏輯上很 OK ,但 問題出在 memcpy 這隻函式上面 。一般人可能會認為, memcpy 是直接做 sequential 的拷貝動作,也就是程式會先把把 i+1 的元素拷貝到 i ,然後才會把 i+2 的元素拷貝到 i+1。很直覺,但是上面這個想法是誰說的? 來讀讀看 manual 吧! The memcpy() function copies n bytes from memory area src to memory area dest.  The memory areas must not overlap .