如果要在Octopress使用數學符號,首先先安裝 kramdown
1 | gem install kramdown |
接著修改_config.yml
將rdiscount改成kramdown
將以下這段代碼塞入 /source/_includes/custom/head.html
解決滑鼠右鍵按下會一片空白的問題
如果要在Octopress使用數學符號,首先先安裝 kramdown
1 | gem install kramdown |
接著修改_config.yml
將rdiscount改成kramdown
將以下這段代碼塞入 /source/_includes/custom/head.html
解決滑鼠右鍵按下會一片空白的問題
ports是FreeBSD安裝軟體的主要途徑,在安裝FreeBSD的時候記得選取Port Collection。
Portsnap 是 FreeBSD 6.0之後所採用的更新Ports方案,以下是簡單介紹。
首先使用 portsnap fetch 抓取Server中的Snapshot,接著使用 portsnap extract 解開存入/usr/ports中。 兩個指令也可以合併一起使用 portsnap fetch extract 。
跟上面一樣的方法,先 portsnap fetch 抓取Snapshot,接著 portsnap update 更新ports資料:也可以 portsnap fetch update 一起使用。
在 /usr/ports下,打上 make search name=”xxx”*,就可以找到xxx有關的ports。
在對應的 ports中,打上 make install 即可安裝, make clean 會將中間產物清除,同樣的可以使用 make install clean來完成上面兩件事。
同樣進入對應的ports,打上 make deinstall
先從ports當中安裝portmaster。更新port colecction,接著打 portmaster -ayD 全部更新,要對portmaster有更進一步了解,請參考底下網頁。
先從 C++ Standard看起
The C++ Standard allows, in 5.3.5/5, pointers to incomplete class types to be deleted with a delete-expression. When the class has a non-trivial destructor, or a class-specific operator delete, the behavior is undefined. Some compilers issue a warning when an incomplete type is deleted, but unfortunately, not all do, and programmers sometimes ignore or disable warnings.
當呼叫deleter時,僅會釋放pointer所佔據的空間,由於不知道他的Destructor有沒有其他的行為,因此不會呼叫其Destructor。
以下是一個範例
在各大編譯器下給出的錯誤訊息
1 | warning C4150: deletion of pointer to incomplete type 'Object'; no destructor called |
1 | deleter.cpp: In function 'void delete_object(Object*)': |
1 | deleter.cpp:4:2: warning: deleting pointer to incomplete type 'Object' may cause |
解決方式也很簡單,在deleter.cpp中加入 #include “object.h” 即可。
或是參考 Check Delete Item
Valgrind是一套用來動態分析程式的框架,他提供一組程式,用來測試,最佳化,及幫助改善程式的方案,你也可以自行開發工具加入Valgrind框架裡面,幫助測試你的程式。
目前的Valgrind套件主要包含了
我們以最常遇到的Memory Leak來介紹, 編譯的時候記得加-g帶除錯參數
以下是Valgrind分析的結果
1 | $:~/test$ valgrind --tool=memcheck --leak-check=full ./main |
由於我們有待除錯參數,所以我們可以發現Memory Leak發生在main.cpp的第三行。
Valgrind不只可以偵測一般的執行檔,連Static Library跟SharedObject都可以偵測,只要記得編譯時帶除錯參數。
之前實驗出來的結果,做個筆記,以免日後忘記。
由於現在的C++編譯器都會做某種程度的最佳化,以GCC來當範本,加上-fno-elide-constructors 參數避免Copy elision。
以下是我們的程式碼。
而第一版的執行結果如下
1 | Constructing! 1 |
從結果我們可以發現,get函數裡面的f,就是id為1的物件,而這個物件在函數結束之後就結束生命週期。而id為2的物件就是get回傳的暫時物件。當回傳時會複製f的內容,而生命週期在main中的foo f = get();之後也跟著消失,從這邊可以看到,我們產生了一個物件,複製了兩份物件,如果當物件體積大的時候,大量的複製/銷燬這種損失是巨大的。
接著介紹
Returning temporary object and binding to const reference
第二版的程式碼
來看執行結果
1 | Constructing! 1 |
看到少了一個Object生成,這是由於C++ Standards Temporary objects 中有這麼一段話。
A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
所以這個暫時物件的生命週期就跟main的生命週期一樣長,無需再複製一份。
在Linux下尋找text pattern的方法。
方法一:使用 find 跟 xargs 共同使用
find dir/ | xargs grep str
這方法會搜尋底下的子目錄
find file | xargs grep str
搜尋檔案裡面是否出現text pattern
方法二: 直接使用grep
grep [-r] str dir/*
搜尋目錄下的所有檔案,-r表示是否蓮子目錄一起搜尋
grep str file
搜尋檔案裡面是否出現text pattern
記錄一下JNI的建立跟使用方法,在Linux底下驗證成功。
以下是一個簡單的範例
裡面做的事情很簡單,載入Shared Object,呼叫 Native Code。
第一步: 接著編譯 Java Code 產生 class 檔
1 | $ javac HelloWorld.java |
第二步: 產生 HelloWorld.h Header File
1 | $ javah -jni HelloWorld. |
產生出來的 Header File長這個樣子
第三步: 撰寫對應的Native Code
做的事情也很簡單,就是印出Hello World而已
第四步: 產生 Shared Object
1 | $ gcc -I"/usr/lib/jvm/java-7-openjdk-amd64/include" -fPIC -shared -o libHelloWorld.so HelloWorld.c |
此時libHelloWorld.so會跟HelloWorld.class在同一個目錄中
第五步: 執行,將LibraryPath指向當前目錄
java -Djava.library.path=
pwd
HelloWorld
可以看到正確的結果。
之前是介紹如何從 Java 呼叫 C++ 的 Native Code,現在要說的是如何從C++建立 Java Virtual Machine,進而執行 Java Code。
第一步: 寫好Java Code且編譯
這裡準備的 Java Code
編譯它
1 | $ javac HelloWorld.java |
第二步:撰寫C++的程式碼且編譯
編譯它
1 | $ g++ -I"/usr/lib/jvm/java-7-openjdk-amd64/include" -L"/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server" Hello.cpp -ljvm -o Hello |
第三歩: 設定 LD_LIBRARY_PATH
1 | $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server |
第四歩: 執行程式
1 | $ ./Hello |
gropf是gnu工具之一,在編譯的時候加入了profiling的source code,執行時統計user space的執行資料,可以得到每個function的被呼叫次數,執行時間,呼叫關係等。
以下是一個簡單範例
##Quick Start
先用gcc編譯程式
1 | gcc hello.c -o hello -pg -g |
-pg表示開啟profiling功能,如果要得到帶注視的程式碼清單,需加上-g。
執行程式
1 | ./hello |
此時會產生 gmon.out檔
使用gprof對程式進行分析
1 | gprof hello gmon.out -p |
得到每個函數所佔用的執行時間
1 | gprof hello gmon.out -q |
得到call graph,每個函數的呼叫關係,
1 | gprof hello gmon.out -A |
得到帶注釋的source code清單,列出每個函數的呼叫次數。