【问题标题】:Returning a pointer to a structure malloc'ed in a function返回指向函数中分配的结构的指针
【发布时间】:2015-02-05 12:06:29
【问题描述】:

我正在使用一个函数来 malloc 并为哈希函数初始化一些内存,如下所示:

int main (int argc, char * argv [])
{
  Bucket * hashTable;
  hashTable = createHashTable();
  ...

在'main.c'中

另一个文件中调用的函数是这样的:

Bucket * createHashTable()
{
  Bucket * hashTable = malloc ( sizeof(Bucket) * HASHSIZE);
  int c=0;
  for (c=0;c<HASHSIZE;c++)
  {
    hashTable[c].key=NULL;
    hashTable[c].text=NULL;
    hashTable[c].next=NULL;
  }
  return hashTable;
}

我的程序使用“-pedantic -Wall”可以干净地编译,但是会出现段错误。使用 gdb,我得到了这个:

Reading symbols from hash...done.
(gdb) break 11
Breakpoint 1 at 0x400990: file main.c, line 11.
(gdb) run
Starting program: /home/user/Projects/random/hash 

Breakpoint 1, main (argc=1, argv=0x7fffffffdf78) at main.c:11
11    hashTable = createHashTable();
(gdb) print hashTable
$1 = (Bucket *) 0x400520 <_start>
(gdb) print * hashTable
$2 = {
key = 0x89485ed18949ed31 <error: Cannot access memory at address 0x89485ed18949ed31>, 
text = 0x495450f0e48348e2 <error: Cannot access memory at address
0x495450f0e48348e2>,    next = 0xc74800400a90c0c7}
(gdb) 

带有结构“Bucket”定义的标头部分:

typedef struct bucket{
  char * key;
  char * text;
  struct bucket * next;
} Bucket;

这是范围问题吗?当函数完成时,它是在杀死我的 malloc 内存还是什么?

平台是64位Linux,这次malloc()返回的地址是0x1665010——我想如果失败了会是NULL。

编辑:在此之后的下一个函数,在 main.c 中,尝试向表中添加一个条目:

printf("Adding banana...\n");
addItem("Banana", "Bananas are yellow", &hashTable);

(是的,是的 - 香蕉,我知道)功能是:

void addItem(char * key, char * data, Bucket ** table)
{
  unsigned int hashkey;
  hashkey=hash(key);
  printf("%lu\n",strlen(key));
if (!table[hashkey]->text) /* SEGFAULTS HERE */
{
  table[hashkey]->key=key;
  table[hashkey]->text=data;
}
else
{
  Bucket * newListElement = malloc(sizeof(Bucket));
  newListElement->key=key;
  newListElement->text=data;
  newListElement->next = NULL;
  table[hashkey]->next = newListElement;
}

}

【问题讨论】:

  • 这似乎是有效的。你在哪个平台? malloc 是返回有效地址还是失败(返回 NULL)?
  • 为了帮助您验证这一点,您应该提供一个完整的最小示例。例如,您包含哪些头文件? Bucket的定义是什么?等等……
  • 等等,你确定它在那条线上崩溃了吗?您对 GCC 的 break 11 命令将在 行执行之前中断。
  • 它在下一行崩溃,我会更新帖子...
  • 我认为内存可能没有正确初始化,所以上面突出显示的 if 测试失败了。

标签: c function pointers scope malloc


【解决方案1】:

这一行:

if (!table[hashkey]->text)

应该是:

if ( !(*table)[hashkey]->text )

类似地在以下几行中。在这个函数中,table实际上是一个指向main中名为hashTable的变量的指针。

解决此错误的另一种方法是使函数采用Bucket *,而不是传递hashTable 的地址。该函数似乎不需要知道hashTable 的地址,因为它只是将东西放在表中。

【讨论】:

  • 成功了,太好了,谢谢!这是否意味着它是按值传递的,因此对表的更新不会超出函数范围?
  • 您不会在函数中的任何位置更新table(除非您没有发布更多代码)。不要将tabletable 所指向的内容混淆。
【解决方案2】:

我曾尝试重现此问题,但未能成功。

所以我唯一的猜测是你可能没有向你的主模块提供正确的函数签名,在那里它被称为int createHashTable()。这应该会导致警告,如果您有 64 位指针和一个 32 位 int,您会丢失结果指针的高 32 位。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多