我可以在c中指定一个类似Java的“构造函数”吗?

问题描述:

我想'构造'(阅读:malloc和memset)我的散列表c。要做到这一点,我创建了一个功能如下:我可以在c中指定一个类似Java的“构造函数”吗?

int maketable(struct hash_entry **table, int size){ 

    table = (struct hash_entry **)malloc(size*sizeof(struct hash_entry *)); 
    int i = 0; 
    for (; i<size; i++) { 
     memset(table[i], '\0', sizeof(struct hash_entry *)); 
    } 
    return 0; 

} 

鉴于该表将被宣布为

struct hash_entry **table[size] 

输入此代码之前,当我从maketable回到我不会失去任何东西,对?

编辑: 是否合格tablemaketable()保证,只要我改变数据,要,这些变化将被保存table点?

编辑II: 我试图指针数组分配给指针hash_entries

+1

我不明白。你在堆栈中为变量分配内存,然后在函数中重新分配一些内容? - 此外,'table'是一个局部变量。你正在分配一些东西,并将它分配给'table',当函数返回时它将消失,导致内存泄漏。 – 2010-01-26 23:01:47

+0

问题是我也不太明白。我的struct hash_entry ** table [size]声明是否为我隐式分配内存?在这种情况下,当我声明它们时,我仍然需要为自己的hash_entrys提供malloc,对吧? – 2010-01-26 23:03:32

+1

该声明为指向堆栈上类型为“hash_entry”的指针的大小为“size”的数组分配内存。它不会为阵列元素要指向的位置分配内存。 – 2010-01-26 23:05:01

您的代码正在分配给本地table变量,调用者不受影响。这导致内存泄漏。

在函数之外,你已经声明table为指向struct hash_entry指针的指针数组 - 我猜你只是想要一个指向数组的结构散列条目。

如果您实际上将table声明为数组,则不需要malloc。您只需要一个循环来将其中的每个元素设置为NULL(不要将每个元素的memset设置为零)。

如果目标是分配整个表,这是perhps你在找什么:

struct hash_entry **table; 
... 
int maketable(struct hash_entry ***table, int size){ 

    *table = malloc(size* sizeof **table); 
    int i = 0; 
    for (; i<size; i++) { 
     (*table)[i] = NULL; 
    } 
    return 0; 
} 

这样称呼它

maketable(&table,100); 

我宁愿做返回的表像这样:

struct hash_entry ** maketable(int size){ 
    return calloc(size, sizeof(struct hash_entry *)); 
} 

如果声明struct hash_entry **table[size]真的是你想要的,你需要告诉我们你的maketable()函数实际上应该做什么(例如,你想要一个动态分配的'数组'作为该表中的元素之一吗?

您需要分配的malloc* table结果 - 否则它不会在函数外可见。

此外,使用这种方法的典型方法是声明一个指向散列表的指针,并将该指针的地址传递给该函数。

+0

我该怎么做? – 2010-01-26 23:06:38

+1

'* table =(struct hash_entry *)malloc ...' – 2010-01-26 23:07:38

不可以。您的类型不匹配。

你试图分配散列项(即的table[i]类型是struct hash_entry)的表中,指针到hash_entries(即的table[i]类型是struct hash_entry *),或别的东西的桌子吗?根据你的代码的读法,我假设第一个案例,但让我知道如果这是错误的。

假设你动态分配的struct hash_entry一个表,你在来电表的声明应该是

struct hash_entry *table; // 1 *, no array dimension 

的功能应该是称为作为

int result = maketable(&table, number_of_elements); 

定义 as

int maketable (struct hash_entry **table, size_t size) 
{ 
    int r = 0; 

    // sizeof **table == sizeof (struct hash_entry) 
    *table = malloc(sizeof **table * size); 
    // *ALWAYS* check the result of malloc() 
    if (*table) 
    { 
    size_t i; 
    for (i = 0; i < size; i++) 
     memset(&(*table)[i], 0, sizeof (*table)[i]); 
    r = 1; 
    } 
    return r; 
} 

有几点需要指出。首先,不要投下malloc()的结果。从C89开始,您不需要,如果忘记包含stdlib.h或者没有原型malloc()的范围,则演员会压缩诊断。其次,您可以在对象上使用sizeof运算符而不是类型。这可以帮助减少一些维护令人头痛的问题(例如,如果在参数列表中更改了table的类型,则不必随其更改sizeof呼叫)。

最后,请注意表的地址正在传递给函数;由于我们试图写入指针值,我们必须将指针传递给该指针。

如果你试图创建指针表来struct hash_entry,代码大多是相同的,间接的只是一个额外的级别:

您的来电表的声明应该是

struct hash_entry **table; // 2 *, no array dimension 

的功能应该是称为作为

int result = maketable(&table, number_of_elements); 

定义作为

int maketable (struct hash_entry ***table, size_t size) 
{ 
    int r = 0; 

    // sizeof **table == sizeof (struct hash_entry *) 
    *table = malloc(sizeof **table * size); 
    // *ALWAYS* check the result of malloc() 
    if (*table) 
    { 
    size_t i; 
    for (i = 0; i < size; i++) 
     (*table)[i] = NULL; 
    r = 1; 
    } 
    return r; 
} 

EDIT有一个在maketable实例中的错误;需要在应用下标之前取消table,即(*table)[i]。我们正在将下标应用到table指向,而不是表指针本身。

对不起,有任何混淆。

+0

我想分配一个指向hash_entries指针的表的表。 – 2010-01-27 00:51:48

+0

然后,您需要将该表声明为'struct hash_entry *** table;'。函数中参数的类型需要是'struct hash_entry **** table'。其他一切应该与第二个例子相同。 – 2010-01-27 04:45:38