1

In my below code I am trying to create a dynamically expandable array of memory.

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

#define BLOCKSIZE 5

int hash_table_length = 0;
int *currentblock = NULL;
int size_left;
int *hash_table = NULL;
int *start = NULL;

int *create_hash_table() {

    int *tmp;

    if (currentblock == NULL || size_left == 0) {

        if (currentblock == NULL) {
            currentblock = (int *) malloc( BLOCKSIZE * sizeof(int));
            start = currentblock;
            size_left = BLOCKSIZE;
        } else {
            currentblock = (int *) malloc( BLOCKSIZE * sizeof(int));
            size_left = BLOCKSIZE;
        }
    }
    tmp = currentblock++;
    size_left -= 1;

    return tmp;

}

void build() {

    int hash;

    int i = 0;
    for (i = 0; i < 20; i++) {
        hash = i + 3;

        if (hash_table_length == 0) {

            hash_table = create_hash_table();
            hash_table_length++;
        } else {
            hash_table = create_hash_table();
            hash_table_length++;
        }

        hash_table = &hash;
        printf("hash value is %d\n", *hash_table);

    }
}

int main() {

    build();

// How do I reach the start of the hash table again?
// the below start does not give me the first value
    printf("Hash table first value is %d\n", *start);
    return 0;
}

My problem here is I wish to traverse through the values stored in the hash_table. I am unable to reach to the first element/address of the hash_table. I wish to print out all the values stored in my hash table. How can this be done?

1
  • If you do not absolutely need to build your own dynamic arrays, you may look into Glib's dynamic arrays ... Commented Apr 13, 2015 at 13:28

1 Answer 1

1

In your code the hash values never get stored inside the hash table(inside currentblock). Inside the create_hash_table() function you allocate memory for a new block but never store values inside this block. Thus if you try dereferencing any of these int* locations you might get a garbage value(which may be a 0). This is what is precisely happening inside your main() function when you dereference the start pointer. It is infact pointing to the start of the hash table and as that location is uninitialized it gives an output of 0. To actually store values inside the hash table change the following inside build():

hash_table = &hash;

to:

*hash_table = hash; // Store value of 'hash' inside the memory location pointed to by hash table(which happens to be 'current_block' inside build())

Now if you try running the code, it will output 3.

Coming to the second part of question as to how you'll traverse the entire hash table: It cannot be done using this code. This is because there is no linkage between your malloc'd blocks of integers. The malloc() call can assign any block of free memory from the heap. Thus in the current form you have disconnected blocks of locations which cannot be traversed.

Instead of malloc you can use realloc to increase the size of your current block. realloc allocates memory for the larger block and copies your previous data to this new block. This will essentially allow you to traverse the entire hash table using start.

Here is how you might do that:

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

#define BLOCKSIZE 5

int hash_table_length = 0;
int *currentblock = NULL;
int size_left;
int *hash_table = NULL;
int *start = NULL;

int *create_hash_table() {

    int *tmp;

    if (currentblock == NULL || size_left == 0) {

        if (currentblock == NULL) {
            currentblock = (int *) malloc(BLOCKSIZE * sizeof(int));
            start = currentblock;
            size_left = BLOCKSIZE;
        } else {
            /* Call realloc() to allocate new memory block of size (hash_table_length+BLOCKSIZE) and copy previous data*/
            currentblock = ((int *) realloc(start,(hash_table_length + BLOCKSIZE) * sizeof(int))) + hash_table_length;
            size_left = BLOCKSIZE;
        }
    }
    tmp = currentblock++;
    size_left -= 1;
    return tmp;

}

void build() {

    int hash;

    int i = 0;
    for (i = 0; i < 20; i++) {
        hash = i + 3;

        if (hash_table_length == 0) {

            hash_table = create_hash_table();
            hash_table_length++;
        } else {
            hash_table = create_hash_table();
            hash_table_length++;
        }
        /* Store value of hash inside the hash_table */
        *hash_table = hash;
        printf("hash value is %d\n", *hash_table);

    }
}

int main() {
    int i;
    build();
    printf("Hash table first value is %d\n", *start);

    /* Traverse the hash table */
    for(i = 0; i < hash_table_length; ++i)
        printf("hash_table[%d] = %d\n",i,*start++);
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.