2017-09-24 108 views
1

我一直在通過符號表實現一段時間,現在我對這段代碼爲什麼導致段錯誤感到十分困惑。在雙指針調用qsort導致分段錯誤

symbol_t** symbol_order (sym_table_t* symTab, int order) { 
symbol_t* sort = malloc(symTab->size * sizeof(symbol_t*)); //line 198 
int index = 0; 
for (int i = 0; i < symTab->capacity; i++) { 
    node_t* nodePtr = symTab->hash_table[i]; 
    while(nodePtr != NULL) { 
     sort[index] = nodePtr->symbol; //line 203 
     nodePtr = nodePtr->next; 
     index++; 
    } 
} 
if (order == NAME) { 
    qsort(sort, symTab->size, sizeof(symbol_t*),compare_names); //line 209 
} else if (order == ADDR) { 
    qsort(sort, symTab->size, sizeof(symbol_t*),compare_addresses); 
} 
return sort; 

功能應該返回類型symbol_t的排序後的數組**,其包括從哈希表中的每一個元素。我使用的qsort有兩種比較方法之一:

int compare_names (const void* vp1, const void* vp2) { 
    symbol_t* sym1 = *((symbol_t**) vp1); 
    symbol_t* sym2 = *((symbol_t**) vp2); // study qsort to understand this 
    return strcmp(sym1->name, sym2->name); //line 185 
} 

int compare_addresses (const void* vp1, const void* vp2) { 
    symbol_t* sym1 = *((symbol_t**) vp1); 
    symbol_t* sym2 = *((symbol_t**) vp2); 
    return sym1->addr - sym2->addr; 
} 

我的數據結構如下:

struct sym_table { 
    int  capacity; 
    int  size; 
    node_t** hash_table; 
    char** addr_table; 
}; 
typedef struct sym_table sym_table_t; 

typedef struct node { 
    struct node* next; 
    int   hash; 
    symbol_t  symbol; 
} node_t; 

typedef struct symbol { 
    char* name; /**< the name of the symbol */ 
    int addr; /**< symbol's address in the LC3 memory */ 
} symbol_t; 

我試着用Valgrind的找到故障的根源,但我是很新,所以我不知道該怎麼做。

  • 我初始化了一個大小爲1的新符號表,以便將它保留在一個鏈接列表中 之間。
  • 我在表中添加了3個元素,然後調用 排序函數來使用compare_names函數。
==30693== Invalid write of size 8 
==30693== at 0x4012BA: symbol_order (symbol.c:203) 
==30693== by 0x401522: printList (testSymbol.c:123) 
==30693== by 0x401966: main (testSymbol.c:207) 
==30693== Address 0x5280cd8 is 0 bytes after a block of size 24 alloc'd 
==30693== at 0x4C2DB9D: malloc (vg_replace_malloc.c:299) 
==30693== by 0x401266: symbol_order (symbol.c:198) 
==30693== by 0x401522: printList (testSymbol.c:123) 
==30693== by 0x401966: main (testSymbol.c:207) 
==30693== 
==30693== Invalid write of size 8 
==30693== at 0x4012B7: symbol_order (symbol.c:203) 
==30693== by 0x401522: printList (testSymbol.c:123) 
==30693== by 0x401966: main (testSymbol.c:207) 
==30693== Address 0x5280ce0 is 8 bytes after a block of size 24 alloc'd 
==30693== at 0x4C2DB9D: malloc (vg_replace_malloc.c:299) 
==30693== by 0x401266: symbol_order (symbol.c:198) 
==30693== by 0x401522: printList (testSymbol.c:123) 
==30693== by 0x401966: main (testSymbol.c:207) 
==30693== 
==30693== Invalid read of size 8 
==30693== at 0x4011FD: compare_names (symbol.c:185) 
==30693== by 0x4E7362D: msort_with_tmp.part.0 (msort.c:83) 
==30693== by 0x4E732F6: msort_with_tmp (msort.c:45) 
==30693== by 0x4E732F6: msort_with_tmp.part.0 (msort.c:54) 
==30693== by 0x4E73A7E: msort_with_tmp (msort.c:45) 
==30693== by 0x4E73A7E: qsort_r (msort.c:297) 
==30693== by 0x401308: symbol_order (symbol.c:209) 
==30693== by 0x401522: printList (testSymbol.c:123) 
==30693== by 0x401966: main (testSymbol.c:207) 
==30693== Address 0x3 is not stack'd, malloc'd or (recently) free'd 
==30693== 
==30693== 
==30693== Process terminating with default action of signal 11 (SIGSEGV): dumping core 
==30693== Access not within mapped region at address 0x3 
==30693== at 0x4011FD: compare_names (symbol.c:185) 
==30693== by 0x4E7362D: msort_with_tmp.part.0 (msort.c:83) 
==30693== by 0x4E732F6: msort_with_tmp (msort.c:45) 
==30693== by 0x4E732F6: msort_with_tmp.part.0 (msort.c:54) 
==30693== by 0x4E73A7E: msort_with_tmp (msort.c:45) 
==30693== by 0x4E73A7E: qsort_r (msort.c:297) 
==30693== by 0x401308: symbol_order (symbol.c:209) 
==30693== by 0x401522: printList (testSymbol.c:123) 
==30693== by 0x401966: main (testSymbol.c:207) 
==30693== If you believe this happened as a result of a stack 
==30693== overflow in your program's main thread (unlikely but 
==30693== possible), you can try to increase the size of the 
==30693== main thread stack using the --main-stacksize= flag. 
==30693== The main thread stack size used in this run was 8388608. 
==30693== 
==30693== HEAP SUMMARY: 
==30693==  in use at exit: 524,480 bytes in 13 blocks 
==30693== total heap usage: 15 allocs, 2 frees, 526,528 bytes allocated 
==30693== 
==30693== LEAK SUMMARY: 
==30693== definitely lost: 0 bytes in 0 blocks 
==30693== indirectly lost: 0 bytes in 0 blocks 
==30693==  possibly lost: 0 bytes in 0 blocks 
==30693== still reachable: 524,480 bytes in 13 blocks 
==30693==   suppressed: 0 bytes in 0 blocks 
==30693== Rerun with --leak-check=full to see details of leaked memory 
==30693== 
==30693== For counts of detected and suppressed errors, rerun with: -v 
==30693== ERROR SUMMARY: 4 errors from 3 contexts (suppressed: 0 from 0) 

我敢肯定它是與在那裏我分配的單一陣列把所有的元素上線203和可能的返回類型問題分配錯誤。我標記了錯誤報告中引用的所有行。

有什麼我失蹤了嗎?我試着改變很多東西,就像堆棧溢出中的其他類似帖子一樣,無論是更改還是更多的問題。

回答

0

更改sizeof(symbol_t*)sizeof(symbol_t)。您想爲symbol_t分配存儲空間,而不僅僅是指向它的指針。對於qsort的大小參數也是如此。