如何在C中创建一个自定义大小的数组

de90aj5v  于 2022-12-03  发布在  其他
关注(0)|答案(2)|浏览(152)

我有这样的代码

#ifndef hashtable
#define hashtable

// define the maxmium size
#define INITIAL_SIZE 5
#define LOAD_FACTOR 0.7

typedef struct hashtable
{
    int keyArray[INITIAL_SIZE];

    // 1d array of strings with maximum length 100 (plus '\0 character')
    char valueArray[INITIAL_SIZE][100 + 1]; 
    bool isActiveArray[INITIAL_SIZE]; // for deleting elements

    int count;
    int capacity;
    double loadFactor;

    // true: linear probing, false: quadratic probing
    bool collisionHandler;

} table;

#endif

hashtable.h文件中
其中我定义了一个带有键数组和值数组等的哈希表。我对如何调整哈希表的大小感到困惑,因为每当创建一个新的结构体以调整大小时,我都会遇到INITIAL_SIZE无法更改的问题,尤其是在#define语句中,尽管我想创建一个容量为2*INITIAL_SIZE的新表,等等。
下面是我的initTable()代码,我在这里创建了一个表,以防它有帮助

void initTable(table* p, int size, double loadFactor, bool collisionHandler) {
    // constructor
    p->count = 0;
    p->capacity = size;
    p->loadFactor = loadFactor; 
    p->collisionHandler = collisionHandler;

    memset( p->keyArray, 0, sizeof p->keyArray );
    memset( p->valueArray, 0, sizeof p->valueArray );
    memset( p->isActiveArray, 0, sizeof p->isActiveArray );    
    
}

如何调整数组大小,即使完全删除INITIAL_SIZE,也可以接受任何建议
谢谢你的帮助皮尤

wj8zmpe1

wj8zmpe11#

宏(定义)不是变量,它们在编译前被它们的值替换,所以在你的代码中所有的INITIAL_SIZE都将被替换为5。
当您在程式码中宣告变数时,它会静态地配置在堆栈上,而且其大小是固定的。您无法变更结构中数组的大小,因此您需要将数组放在结构之外,并使用指向它的指标,如下所示:

typedef struct hashtable
{
    int    *keyArray;
    char   *valueArray; 
    bool   *isActiveArray;
    
    int    count;
    int    capacity;
    double loadFactor;
    
    bool   collisionHandler;
} table;

然后您需要动态分配带有malloc的数组。malloc函数接受您想要分配的大小参数,并返回一个指向已分配区域(在堆上)的指针。例如:

table p;
int   size = 5;
p.keyArray = malloc(size * sizeof(int)); // sizeof is a c operator that return the size of a type in bytes

if (p.keyArray == NULL)  // it is a good practice to protect a malloc by checking its return value
   exit(1);

//p.keyArray now points to an array of size 5, you can now use it like any other array

当您不再需要该数组时,必须使用free函数释放已分配的内存

free(p.keyArray);

最后,这里是执行数组大小调整的完整代码:

void resize(int **array, int old_size, int new_size)
{
    int *new_array = malloc(new_size * sizeof(int)); // allocate the new area
    if (!new_array) // protect the malloc
       exit(1);
    memcpy(new_array, *array, old_size * sizeof(int)); // copy the content from the old area to the new one
    free(*array); // free the old area
    *array = new_array; // and change the pointer of the old area
}

或使用realloc:

void resize(int **array, int new_size)
{
    *array = realloc(*array, new_size * sizeof(int));
    if (!*array)
        exit(1);
}

edit:正如Neil提到的,realloc方法更好,因为你让malloc做内部优化(如果初始区域旁边的区域足够大,它只会扩展这个区域,这样就避免了复制数组的内容)。我只是想向你展示第一个版本的malloc逻辑。

ctrmrzij

ctrmrzij2#

@jgiron42的答案几乎是完美的使用malloc重新分配和使用整数,字符和布尔指针在hashtable. h中的列表,在我的代码/问题中,使它完全工作的唯一方法是当复制一个新的int* 键数组时,它需要像这样做-〉memcpy(new_keys, *keys, old_size * sizeof(int));,而不是什么工作的字符和布尔数组memcpy(new_bools, *bools, old_size);

相关问题