c程序設計
    最近程序發現了個奇葩現象,即從文件載入的證書鏈用openssl校驗是通過的,而用curl遠程獲取的就校驗失敗,錯誤碼7。而這些內容寫入文件在下一次程序啟動時載入校驗,又是成功的。

    排查了各種內存泄露、不可見字符的可能性后。突然想起來是不是libcurl靜態鏈接了openssl跟主程序動態鏈接的打架。查看后發現libcurl未靜態鏈接openssl。

     不過這也是一個啟示。想起來既然curl也用到了openssl,那么它在最后cleanup的時候會不會把全局的openssl數據結構給釋放掉。


     嘗試了一下,果然好了。原來我在一個函數里開頭調用curl_global_init,結尾調用curl_global_cleanup。這樣的話在程序結束時就會釋放openssl的全局數據結構。導致后續調用證書校驗報錯。

     不過openssl也不夠友好,報證書簽名錯誤,讓人很難聯想到是初始化問題。


      不過aes加密部分并不受這個影響。
    一直對內存操作的速度沒有數值概念,只泛泛的知道memset影響效率,反復分配釋放內存影響效率,具體速度如何,從來沒試過,今天試驗了一下。

    寫了個程序,分配一個指針數組,挨個分配內存,然后挨個釋放。使用的是一臺2核16g內存的虛擬機。gcc版本3.4.2

    先是分配了1w個100字節塊,發現5ms以內即可完成。
    然后擴大到500字節塊,速度沒什么變化。

    然后分配100w個字節塊,平均需要270ms左右。
    字節塊擴大的2k左右,大概5s完成。
    擴大到5k左右,大概12s左右。
    以上數據均為malloc+memset數據和calloc數據,兩者不相上下。

    只malloc不memset,大概能縮短20%左右,可見memset對速度還是有一定影響的,不過對于性能要求不是那么嚴苛的程序,設置一下提高程序穩定性也是值得的。避免某變量忘記初始化出現野值的問題。



Tags:

printf空指針NULL的問題

[| 不指定 2012/05/16 17:52]
    今天發現程序中有幾個地方在沒有校驗指針為NULL的時候進行了打印日志操作,在字符串處理函數中使用NULL指針不是什么好事,研究了一下,發現在一些的linux發行版中,printf("%s",NULL)會打印一個“(NULL)”,而在solaris中則會出core,windows下也沒有問題。

    可見不同的c庫對于這個行為的實現不太一致。

    使用中還是要盡量避免這種用法,不過每次打日志前都要判斷指針情況確實比較惡。




    前兩天在用lua_next遍歷一個lua表的時候遇到了:PANIC: unprotected error in call to Lua API (invalid key to 'next')  仔細檢查了下代碼和堆棧信息,發現沒有問題,但為什么會說遍歷失敗呢?

    找到文檔看了下,原來lua_tolstring只支持number和string類型,但是對于number類型,在取值后也會轉換其在表中的實際內容為string,而我遍歷的表是使用默認自增索引作為key的,這樣對key調用這個函數會導致key變成字符串,因而遍歷有問題。

    如果表的key不一定是string,而又要用lua_tolstring獲取它的值,那么建議先在棧上復制一份,然后對于復制的值進行獲取。





Tags:
    忘記之前從哪看過的一個文章說不要在for、while等循環內聲明變量,因為每次都會重復分配空間,很慢。

    今天發現一個模塊把變量聲明都放到while里面了,看了下代碼沒有發現必須聲明在里面的原因,于是開始懷疑是不是聲明在內外是差不多的。

    于是測試了一下:
引用

int main() {
    int i = 0;

    for(;i < 10000000; i++) {
        int b;
        b++;
    }

    return 1;
}


使用gcc 編譯,把int b放在循環內外試了試,用time ./a.out查看執行時間,發現用時基本相同。
添加-O2優化選項,執行時間均縮減到之前的1/3,內外兩種方式時間依然相同。
定義了一個struct實驗了下,結果相同
也就是說棧上元素的操作不必糾結于變量聲明于何處。

嘗試了下堆上元素操作,在預料之內:時間差距巨大,因為重復分配釋放內存。

所以對于棧上元素,聲明放在循環里和循環外是一樣的。堆上元素不同,需注意。

另,仍然需要注意一些計算操作需要放在循環外,比如求大小之類的,避免循環的每個周期重復計算。


原因猜測:1, cpu對棧操作有優化,速度非常快。
2,編譯器的基本優化中會優化(gcc沒有使用-O參數時仍會優化)
具體原因待深究
    今天編譯lua程序時發現總是報缺少dlopen和pow之類的,需要手動加-lm -dl才行。感覺有點奇異,按我的理解來說使用靜態庫是不需要考慮依賴的。仔細研究了下,發現很多誤區。
    首先用靜態庫編譯出的可執行文件是不考慮庫依賴的,但并不代表用靜態庫時也不需要考慮。靜態庫在編譯時是不檢查函數是否被實現的,也就是說只需要.h即可。
    其次,靜態庫和動態庫其實區別很大,靜態庫只是編譯出.o的一個打包的文件,而動態庫添加了鏈接信息。

    這樣的話靜態庫還有一個特性,就是在靜態庫中可以調用一些預留接口,而把這些接口留待以后實現。
Tags:
    今天程序出了一個core,是strcmp的時候有一個參數沒有判斷為NULL導致的,當我編寫了一個小程序:

引用
#include
int main()
{
strcmp(NULL, "“);
return 1;
}

測試的時候發現程序跑的毫無問題。
編譯參數是gcc -g -O0,沒有開任何優化。

gdb進去后發現strcmp根本沒有被執行,改成int a = strcmp(NULL, "");后,出core了。

看來編譯器默認還是提供一定優化的。

另外需要注意strcmp不會檢查參數(效率考慮),所以需要自己檢查。
    最近程序遇到一個小概率出core的bug,高壓力下大概10分鐘左右就會出core,gdb查看發現一個指針高四字節被置0xffffffff了,低四字節正常。
    該指針是局部變量,存放在棧上,排除了線程間同步互斥寫壞數據的可能。
    該指針前后變量均正常,都是指針,排除了寫越界的可能。

    通過日志查看,在返回該指針的函數返回前,指針正常,返回后高四字節即被置0xffffffff了。推斷應該是函數返回的過程中遭到了破壞。

    但不知道為什么返回的過程中會出錯,請教了下組內高工,高人就是高人,一聽問題描述就表示應該是函數聲明的問題。

    原來,在調用另一個so文件中的函數時,如果沒有該函數的聲明,由于從該so的符號表里可以找到函數,所以編譯可以通過,但gcc會把這個函數返回值按默認的int處理,這種情況下,32位機編譯的程序是沒問題的,但64位機上指針是8字節,導致高四字節數據丟失。但返回的指針超過int值域時,高四字節數據丟失,導致指針被破壞。

   所以函數聲明還是不可或缺的。
Tags: ,
分頁: 1/1 第一頁 1 最后頁 [ 顯示模式: 摘要 | 列表 ]
黄se大片全集,s8视频 情色视频,国产在线久久播放,天天鲁天一鲁,第一色色资源站 一色屋,3X免费视频 <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>