標籤:

C++中如何載入100K+的常數數組?

需從文本中讀取大量常數。除了使用include,如何將這些數據存儲到一個數組裡,同時又能高效地使用?


CreateFileMapping function (Windows)

答案是使用這個函數,並且跟文本文件說再見。


in data.h

extern int global_data[];

in http://data.cc

int global_data[] = {
// 100K numbers
};


親測有效(Ubuntu 14.04 x86_64)

$ dd if=/dev/urandom of=data.bin bs=1k count=100
100+0 records in
100+0 records out
102400 bytes (102 kB) copied, 0.0241125 s, 4.2 MB/s

$ hexdump -C data.bin | less
00000000 e1 02 d7 dd 5b 20 4f bd ...

$ ld -r -b binary -o data.o data.bin

$ cat read_data.c
#include &

extern unsigned char _binary_data_bin_start;
extern unsigned char _binary_data_bin_end;
extern unsigned char _binary_data_bin_size;

int main()
{
unsigned char *pdata = _binary_data_bin_start;
printf("size: %ld
", (long)_binary_data_bin_size);
while(pdata &< _binary_data_bin_end) { printf("%ld: %02X ", pdata - _binary_data_bin_start, *pdata); pdata++; } return 0; } $ gcc -Wall read_data.c data.o $ ./a.out | less size: 102400 0: E1 1: 02 2: D7 3: DD 4: 5B 5: 20 6: 4F 7: BD ...

參考資料:

  • Ross Burton

  • Linking a binary blob with GCC


內存映射,你值得擁有[滑稽]


1.假設你的常數數組為int類型,保存在一個文件中data.txt,每行一個,你先將int轉換為位元組序"xxxx..."

$cat data.txt | perl -ne "chomp;@a=split //, sprintf "%08x", $_;print map{"\x$a[2*$_]$a[2*$_+1]"} (3,2,1,0)"

2.然後定義一個array.c和array.h文件

#array.c

const char * const array = "xxxx";

/*

把上一步的輸入考不到這兒,輸入為了輸出漂亮一些,可以多行,注意xXX中間不要斷開。

*/

//array.h

#ifndef ARRAY_H

#define ARRAY_H

extern const char * const array

#endif

可能存在對齊有問題

3.使用

#include&

int main(int argc, char**argv){

int *intarray = (int*) array;

}

這種方式實現,整數數組存儲在.rodata段上,是無法修改的。 強轉之後也無法修改。

如果你對對齊要求很非常嚴格,建議採用彙編編寫,彙編的偽指令.align可以幫助你將數組的起始地址對齊在4位元組的邊界上。


推薦閱讀:

C++自學用書推薦?
自學計算機圖形學要哪些基礎?只用c語言可以嗎?
long Rq = 1432567; int *x; x = (int *)Rq; printf("%d",*x); 錯誤在哪裡?
為什麼說:不要使用 dynamic_cast, 需要運行時確定類型信息, 說明設計有缺陷?
c++函數如何接受數量不定的函數參數?

TAG:C | CC |