在双指针上调用qsort导致分段错误

时间:2017-09-24 21:37:02

标签: c arrays pointers 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个元素然后调用了 sort函数使用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行,也许是返回类型问题。我已经标记了错误报告中引用的所有行。

有什么我想念的吗?我已尝试根据Stack Overflow上的其他类似帖子改变很多东西,无论是没有变化,还是更多问题。

1 个答案:

答案 0 :(得分:0)

sizeof(symbol_t*)更改为sizeof(symbol_t)。您想为symbol_t分配存储空间,而不仅仅是指向它的指针。类似地,对于qsort的大小参数。