问题描述:

Basically I am trying to build a hash structure of cstrings that I can re-assign the member stringnode_ref *nodes to a larger dimension array (malloc a new one, re-hash the existing values, and delete the old one) when the hash begins to fill up.

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;

}

compiling with:

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

this all compiles fine with no errors but upon declaring stringtable_ref table = new_stringtable(); in the main(), the program segfaults at sTable->nodes[index]->key = 0;. Any thoughts?

网友答案:
sTable->nodes = malloc(31 * sizeof(struct stringnode));
for( index = 0; index < 31; index++ ){
    sTable->nodes[index]->key = 0;

here's the problem: the segfault occurs because you don't allocate memory for sTable-nodes[index], so it may be garbage (when I examined your code on GDB under OS X, it was actually NULL).

Solution: add the following line as the first line of the body of the for loop:

sTable->nodes[index] = malloc(sizeof(*(sTable->nodes[index])));
网友答案:

You define the nodes element of stringtable as a pointer to stringnode_ref, that is, as a pointer to pointer to struct stringnode. Since you do sTable->nodes = malloc(31 * sizeof(struct stringnode));, you calculate the size of sTable->nodes as if it was pointer to struct stringnode (which it isn't).

Possibly, you want to define stringtable like this:

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

You can then initialize the nodes using

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

Here is the whole code that compiles correctly and does not show memory errors with valgrind. Compilation with gcc -Wall --pedantic -o ttt -g ttt.c; checking for memory errors with valgrind --tool=memcheck ./ttt. Please note how sizeof() is used and implement it in your own code.

#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 ) ;
}

P.S. The attempt to compile the code as you have described in your edited post results in the following:

:~/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’
相关阅读:
Top