-1

基本上我正在尝试构建一个 cstrings 的哈希结构,stringnode_ref *nodes当哈希开始填满时,我可以将成员重新分配给一个更大的维度数组(malloc 一个新的,重新哈希现有的值,并删除旧的) .

字符串表.c:

#include <stdio.h>
#include "stringtable.h"

struct stringnode{
    hashcode_t key;
    cstring value;
};

struct stringtable{
    size_t dim;
    size_t numEntries;
    stringnode_ref *nodes;
};

stringtable_ref new_stringtable(){
    size_t index = 0;
    stringtable_ref sTable = malloc(sizeof(struct stringtable));
    sTable->dim = 31;
    sTable->numEntries;
    sTable->nodes = malloc(31 * sizeof(struct stringnode));
    for( index = 0; index < 31; index++ ){
        sTable->nodes[index]->key = 0;
        sTable->nodes[index]->value = NULL;
    }
    return sTable;
}

字符串表.h:

#ifndef __STRINGTABLE_H__
#define __STRINGTABLE_H__

#include <stdlib.h>
#include <inttypes.h>

typedef char *cstring;

typedef uint32_t hashcode_t;

typedef stringtable *stringtable_ref;

typedef stringnode *stringnode_ref;

stringtable_ref new_stringtable();

#endif // __STRINGTABLE_H__

oc.c:

#include <stdlib.h>
#include <stdio.h>
#include "stringtable.h"

int main( int argc, char **argv ){
    stringtable_ref table = new_stringtable();
    return EXIT_SUCCESS;
}

编译:

gcc -g -O0 -Wall -Wextra -std=gnu99 -c stringtable.c
gcc -g -O0 -Wall -Wextra -std=gnu99 -c oc.c
gcc -g -O0 -Wall -Wextra -std=gnu99 -o oc stringtable.o oc.o

这一切都编译得很好,没有错误,但是在stringtable_ref table = new_stringtable();main() 中声明时,程序在sTable->nodes[index]->key = 0;. 有什么想法吗?

4

2 回答 2

1
sTable->nodes = malloc(31 * sizeof(struct stringnode));
for( index = 0; index < 31; index++ ){
    sTable->nodes[index]->key = 0;

这就是问题所在:发生段错误是因为您没有为 分配内存sTable-nodes[index],因此它可能是垃圾(当我在 OS X 下的 GDB 上检查您的代码时,实际上是NULL)。

for解决方案:将以下行添加为循环体的第一行:

sTable->nodes[index] = malloc(sizeof(*(sTable->nodes[index])));
于 2012-10-16T06:55:57.467 回答
0

您将 的nodes元素 定义stringtable为指向 的指针stringnode_ref,即指向指向 的指针的指针struct stringnode。既然你这样做sTable->nodes = malloc(31 * sizeof(struct stringnode));了,你计算的大小sTable->nodes就好像它是指针一样struct stringnode(它不是)。

可能,您想像这样定义 stringtable:

struct stringtable{
  size_t dim;
  size_t numEntries;
  stringnode_ref nodes;
};

然后,您可以使用初始化节点

sTable->nodes[index].key = 0;
sTable->nodes[index].value = NULL;

这是正确编译并且不显示 valgrind 的内存错误的整个代码。编译gcc -Wall --pedantic -o ttt -g ttt.c;使用 . 检查内存错误valgrind --tool=memcheck ./ttt。请注意如何sizeof()在您自己的代码中使用和实现它。

#include <stdlib.h>

typedef char *cstring;

struct stringnode{
    int key;
    cstring value;
};

typedef struct stringnode *stringnode_ref;

struct stringtable{
    size_t dim;
    size_t numEntries;
    stringnode_ref nodes;
};

typedef struct stringtable *stringtable_ref;

stringtable_ref new_stringtable(){
    size_t index = 0;
    stringtable_ref sTable = malloc(sizeof( *sTable ) ) ;
    sTable->dim = 31;
    sTable->nodes = malloc(31 * sizeof( *sTable->nodes ) ) ;
    for( index = 0; index < 31; index++ ){
        sTable->nodes[index].key = 0;
        sTable->nodes[index].value = NULL;
    }
    return sTable;
}


int main(int argc, char *argv[]) {
  stringtable_ref table = new_stringtable();
  exit( EXIT_SUCCESS ) ;
}

PS尝试编译您在编辑后的帖子中描述的代码会导致以下结果:

:~/tmp$ gcc -g -O0 -Wall -Wextra -std=gnu99 -c stringtable.c
In file included from stringtable.c:2:
stringtable.h:11: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
stringtable.h:13: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
stringtable.h:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘new_stringtable’
stringtable.c:12: error: expected specifier-qualifier-list before ‘stringnode_ref’
stringtable.c:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘new_stringtable’
于 2012-10-16T07:01:02.820 回答