-1

基本的に、ハッシュがいっぱいになり始めたときに、メンバーをより大きな次元配列に再割り当てできるcstringのハッシュ構造を構築しようとしていますstringnode_ref *nodes(新しいものをmallocし、既存の値を再ハッシュし、古いものを削除します) .

stringtable.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;
}

stringtable.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;

ここに問題があります: にメモリを割り当てていないために segfault が発生するため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->nodesstruct 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 に答える