2012-12-13 51 views
0

Segfault我發現自己無法診斷。(C)傳遞給func的指針不同於原始的

我有一個基準FUNC chrono接收指針數組strings到隨機生成的字符串和相應sizes的陣列。對於調試,我打印strings(指向指針的指針),strings[1](其中之一)和sizes(指針)。 (我也在chrono中打印了一些字符串,可以肯定的是,它們與產生它們的func中的原始內容進行比較:所有的都沒有問題。)基準測試是一種將一串字符串提供給字符串池:

void pool_store_pack (StringPool * pool, 
    char ** strings, size_t * sizes, uint n_new); 

對於調試,我在pool_store_pack中打印相同的數據。價值觀是不同的。 strings已更改,並且strings[1]sizes都爲空。下面是一個例子輸出:

strings:0x9842fa8 (n°1:0x984200c) 
sizes:0x9843f48 
some strings: `@PR` `MOB` `TBQ` 

strings:0x804a824 (n°1:(nil)) 
sizes:(nil) 
segmentation fault (core dumped) 

我試圖將錯誤減少到一個簡單的形式,但它是很難正是因爲它的測試代碼,而不是應用程序代碼,驅動一個自治片庫。當我嘗試重新從頭開始重新編譯這個bug時,我只能得到指針和指針的指針,這些指針在接收函數中與發送函數中的值相同。不過,如果它有幫助,我可以發佈3個相關funcs的代碼(但是你不能運行它,因爲它只是驅動其他funcs)。

我很肯定會錯過一個明顯的觀點,但不能看到它,並且被阻止並且沮喪幾個小時;-)你能幫忙嗎?

編輯:那麼,這裏是整個代碼涉及:

/* Put pack of strings in pool. 
*/ 
void pool_store_pack (StringPool * pool, 
     char ** strings, size_t * sizes, uint n_new) { 
    pool_grow(pool, n_new); 

    // debug ///////////////////////////////////////////////////////// 
    printfl("n_new:%u", n_new); 
    printfl("strings:%p (n°1:%p)", strings, strings[1]); 
    printfl("sizes:%p", sizes); 
    printfl("some sizes: %u %u %u", sizes[1], sizes[3], sizes[9]); 
    printfl("some strings: '%s' '%s' '%s'", strings[1], strings[3], strings[9]); 
    end(); 

    uint i; 
    for (i = 0; i < n_new; i++) pool_store(pool, strings[i], sizes[i]); 
} 

// generate random strings (constants used here are defined somewhere else) 
static char ** data_strings (char ** p_bytes) { 
    char * bytes = malloc(n_strings * l * sizeof(char)); 
    check_mem(bytes); 
    char ** strings = malloc(n_strings * sizeof(char *)); 
    check_mem(strings); 
    char * s; 
    uint i,j; 
    srandom(time(NULL)); 

    for (i=0; i<n_strings; i++) { 
     s = bytes + i*l; 
     s[size] = NUL; 
     for (j=0; j<size; j++) s[j] = '@' + random()%n_letters; 
     strings[i] = s; 
    } 

    //~ for (i=0; i<n_strings; i++) printf("'%s' ", strings[i]); line(); 
    printfl("some strings: '%s' '%s' '%s'", strings[1], strings[3], strings[9]); 
    * p_bytes = bytes; 
    return strings; 
} 

// benchmark 
static void chrono() { 
    printfl ("=== chrono pool ==============================================="); 
    uint i; 
    clock_t t1, t2; 
    float dt; 

    // test data string 
    char * bytes; 
    char ** strings = data_strings(& bytes); 
    // string sizes are all equal to size (3) 
    size_t * sizes = malloc(n_strings * sizeof(size_t)); 
    check_mem(sizes); 
    for (i=0; i<n_strings; i++) sizes[i] = size; 

    // debug /////////////////////////////////////////////////////////////////// 
    printfl("n_strings:%u", n_strings); 
    printfl("strings:%p (n°1:%p)", strings, strings[1]); 
    printfl("sizes:%p", sizes); 
    printfl("some sizes: %u %u %u", sizes[1], sizes[3], sizes[9]); 
    printfl("some strings: '%s' '%s' '%s'", strings[1], strings[3], strings[9]); 

    // now, feed the pool 
    StringPool * pool = stringpool(); 
    t1 = clock(); 
    pool_store_pack(pool, strings, sizes, n_strings); 
    t2 = clock(); 
    end(); 
    dt = 1.0 * (t2 - t1)/CLOCKS_PER_SEC; 
    print("pool data : "); show_pool_data(pool); 
    print("pool stats : "); show_pool_stats(pool, false); 
    printfl("time : %.3f", dt); 

    free(bytes); 
    free(strings); 
} 
+0

獲得的經驗教訓:不要返回自動數組。 – 2012-12-13 19:29:17

+0

請發送更多的代碼。 –

+0

給定'sizes:(nil)',看起來你試圖解引用大小來獲得第一個數組元素,並且失敗。 (即在第15行中,在malloc()之後) – wildplasser

回答

2

OK運行!其實有兩個錯誤,互相影響。首先,錯誤地重新定義了一個靜態常量,給出了一組初始字符串的大小以供給池(實際上只有"",所以這個集合的長度爲1)。其次,2個指令的反轉使得池在初始化之前被使用。交互作用是初始化還使用pool_store_pack爲所述初始字符串提供池。

==>

我有什麼作爲調試輸出(和向您展示)從調用此FUNC pool_store_pack爲池初始化反映的數據,而不是從計時FUNC(因此,strings[1]是零,因爲有隻是初始集合中的一個字符串!)。而sizes是零,因爲它是錯誤地改變了的靜態常量......媽媽咪呀!

感謝大家!不幸的是我不能投票給你,因爲只有評論...

+0

你仍然可以接受你自己的答案,這是完全正確的行爲,以標記問題解決。 – hyde

+0

謝謝,海德,甚至沒有注意到檢查標誌。我會這樣做,但是SO的軟件不會讓我現在(告訴我,我必須等到明天)。 –