Riktig fordeling Memory

stemmer
1

Jeg har følgende konstruksjon:

typedef struct bucket {
    char *key;
    ENTRY *data;
    struct bucket *next;
} bucket;

typedef struct {
    size_t size;
    bucket **table;
} hash_table;

Men jeg har ingen anelse om hvordan å allokere minne for det. Jeg prøvde:

hash_table* ht = malloc(sizeof(hash_table)*101);

for å skape en hashtabellen for 101 oppføringer, men det din't fungere! Kan noen hjelpe meg? Jeg ville virkelig pris på det!

Publisert på 16/12/2008 klokken 08:42
kilden bruker
På andre språk...                            


4 svar

stemmer
9

Det gir ikke mening å bevilge hele 101 (eller hvor mange) bøtter på forhånd, vil du vanligvis tildele dem en om gangen, når du setter inn nye data inn i tabellen.

Det gjør fornuftig å pre-allokere hash tabellen, noe som vil ha en fast størrelse, men det er en rekke bøtte pekere , ikke en rekke bøtter, slik at noen av svarene er feil.

Du vil ha noe som dette, for å skape en en tom hash table, med en fast størrelse bøtte matrise:

hash_table * hash_table_new(size_t capacity)
{
  size_t i;

  hash_table *t = malloc(sizeof *t);
  t->size = capacity;
  t->bucket = malloc(t->size * sizeof *t->bucket);
  for(i = 0; i < t->size; i++)
    t->bucket[i] = NULL;
  return t;
}

Denne koden:

  • Allokerer en hash_table struktur for å holde bordet
  • Initialiserer den størrelsen med angitte kapasitet
  • Allokerer en matrise av bøtte viserne i riktig lengde
  • Gjør at hver bøtte pekeren er NULL (som ikke kan ordentlig gjøres med memset (), så det er ikke trygt å anta at "alle biter null" er veien NULL ser i minnet)
  • Bruker sizeofnår det er mulig, men ikke på typer, så ingen parentes
  • Ikke kaste returverdien av malloc(), siden det er aldri en god idé i C
  • Sjekker ikke returverdien av malloc (), selvfølgelig bør du gjøre det i det virkelige kode

En annen funksjon ville være nødvendig for å gjøre en faktisk hash innsats, som da vil trenge å tildele en ny bøtte, beregn hashverdien fra nøkkelen, velge den riktige plassering i hash tabellens matrise, og sette inn det nye posten finnes.

Svarte 16/12/2008 kl. 08:57
kilden bruker

stemmer
0

Det er et par ting worong med typedef tallet. Forutsatt ved hjelp MSVC.

En enkel måte å erklære hvilke typer du har her vil være noe sånt som;

Dette typedef omfatter _type {} typen, * ptype; format som erklærer type og pekeren til den tilpassede skrive alt på samme tid. Hvis du ser ned i hash_table, du er i stand til å bruke pbucket * bordet, noe som eliminerer ekstra *** i koden din og kan hjelpe når du gjør dynamisk tildeling (hjelpe så mucah som å holde hodet rett om hva tildeling etc .. ). Den opprinnelige typedef, hvis du ser hadde typedef struct bøtte {} bøtte ;, må du i det minste endre en av de to "bøtte" navn du har det når du angir din typedef.

Du må også kaste hvis du bruker C ++ bygge innstillinger, hvis du bruker vanlig C du kanskje ikke trenger skuespillere, slik at malloc linjen vil være (med følgende typedef endringene jeg har gjort);

hash_table* ht = (phash_table) malloc(sizeof(hash_table)*101);

Uansett bør dette tekstutdraget fungere for deg;

typedef struct _bucket {    
    char *key;    
    void *data;    
    _bucket *next;
} bucket, *pbucket;

typedef struct _hash_table {    
    size_t size;    
    pbucket *table;
}hash_table, *phash_table;
Svarte 21/02/2009 kl. 03:30
kilden bruker

stemmer
0

Ikke helt. Antar dette er C, har du sannsynligvis ønsker å gjøre en funksjon:

 hash_table* init_table(size_t size) {
     size_t i;
     hash_table* ht = (hash_table*)malloc(sizeof(hash_table));
     if (ht == NULL) return NULL;
     ht->size = size;
     ht->table = (bucket**)malloc(sizeof(bucket*)*size);
     if (ht->table == NULL) {
         free(ht);
         return NULL;
     }
     for (i = 0; i < size; ++i) {
         ht->table[i] = NULL;
     }
     return ht;
 }

Du må kanskje noen andre felt i det struct.

Hvis du ønsket å være vanskelig, og aldri realloc bøtte, kan du gjøre dette:

 hash_table* init_table(size_t size) {
     hash_table* ht = (hash_table*)malloc(sizeof(hash_table)+sizeof(bucket)*size);
     if (ht == NULL) return NULL;
     ht->size = size;
     ht->table = (bucket**)(ht+1);
     for (i = 0; i < size; ++i) {
         ht->table[i] = NULL;
     }
     return ht;
 }

EDIT: Jeg fikset min bøtte * tabellens å bøtte **

EDIT2: Jeg har blitt kvitt de memsets og lagt feilkontroll for malloc.

Svarte 16/12/2008 kl. 08:48
kilden bruker

stemmer
0

Det hash_tablevil alltid være bare sizeof(hash_table)byte stor. Den tableelement er en peker til en oppstilling av poiinters til bucketelementene. Så du trenger noe som dette:

hash_table* ht = malloc(sizeof(hash_table));
ht->size = 101;
ht->table = malloc(sizeof(bucket*)*ht->size);

Men jeg mistenker at det kan være noen initialisering metoden som følger med det, og du kan da gjøre noe som dette:

hash_table* ht = alloc_hash_table(101);

Uansett, jeg er litt rusten i C, så ta dette med en klype salt.

Svarte 16/12/2008 kl. 08:47
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more