简体   繁体   English

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

[英]Calling qsort on Double Pointer Results in Segmentation Fault

I've been working through a symbol table implementation for a while now and am quite confused on why this bit of code causes a segfault. 我已经研究符号表实现了一段时间了,对于为什么这段代码会导致段错误感到非常困惑。

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;

The function is supposed to return a sorted array of type symbol_t** which includes every element from the hash table. 该函数应该返回一个类型为symbol_t **的排序数组,其中包括哈希表中的每个元素。 I am using qsort with one of two compare methods: 我将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;
}

My data structure is as follows: 我的数据结构如下:

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;

I tried using Valgrind to find the source of the fault but I'm pretty new to it so I'm not sure what to make of it. 我尝试使用Valgrind查找故障原因,但是我对此很陌生,所以我不确定该怎么做。

  • I initialized a new symbol table with size 1 in order to keep it in one linked list. 我初始化了一个大小为1的新符号表,以将其保留在一个链表中。
  • I added 3 elements to the table and then called the sort function to use the compare_names function. 我在表中添加了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) 

I'm pretty sure it has something to do with an allocation error where I allocated the single array to put all of the elements on line 203 and maybe the return type issue. 我很确定这与分配错误有关,在该错误中,我分配了单个数组以将所有元素放在第203行,甚至可能出现了返回类型问题。 I've marked all the lines that are referenced in the error report. 我已经标记了错误报告中引用的所有行。

Is there something I'm missing? 有什么我想念的吗? I've tried changing many things around as per other similar posts on Stack Overflow with either no change or even more problems. 我已经尝试过按照Stack Overflow上其他类似的帖子来更改许多事情,而没有任何改变,甚至还有更多问题。

Change sizeof(symbol_t*) to sizeof(symbol_t) . sizeof(symbol_t*)更改为sizeof(symbol_t) You want to allocate storage for a symbol_t , not just a pointer to it. 您想为symbol_t分配存储空间,而不仅仅是指向它的指针。 Similarly for the size arguments to qsort . 对于qsort的size参数类似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM