【问题标题】:Cannot re-iterate a pointer array无法重新迭代指针数组
【发布时间】:2017-11-10 06:18:09
【问题描述】:

我有一个从文件中读取的项目指针数组。这些项目是typedef structs

我的数组可以调整大小,因为文件包含很多项目。

while (fscanf(fp, "%X %[^\n]", &code, string) != EOF) {
    if (list->length >= list->capacity) {
        list->capacity *= 2;
        list->items = (Item**)realloc(list->items,
            list->capacity * sizeof(Item*));
    }
    item.code = code;
    strcpy(item.string, string);
    list->items[list->length++] = &item;
}

假设 listitem 已经声明。空间已分配给列表。

static List * list; & Item item = { 0, { 0 } };

在代码中较早地声明和初始化。 list 是必要的全局变量。

如果我尝试通过尝试获取第一个值来迭代这个已完成的列表:

printf("line %d: %X\t%-89s\n", 1, list->items[0]->code, list->items[0]->string);

我将从这里获取文件中的最后一个元素。但是,如果我将这个printf 包含在上述while 循环中,我将获得所需的控制台输出(当索引为list->length 时)。

为什么我会遇到这种行为?关于遍历指针有什么我忘记了吗?

【问题讨论】:

  • 永远不要将 realloc 直接插入目标指针 - 始终使用临时变量并检查 NULL
  • 您一直在将指针分配给 same 项!你不应该在每次迭代中malloc new Item。如果你连续穿红色、绿色和黄色的衬衫,彩虹色的不是3个人,只有你穿着黄色的衬衫。
  • 您需要说明ListItem 是如何声明的。看来你在ItemItem* 之间搞砸了
  • @AnttiHaapala 很抱歉,您的类比没有意义。不过,我明白你所说的重复内容。
  • @compolo 但绝对可以!您没有 n 个不同的 Item 对象。只有一个,n 指针指向那个项目

标签: c arrays pointers dynamic-programming traversal


【解决方案1】:

您似乎将item 用作自动Item 对象,因此用指向同一Item 对象的指针填充list->items 数组。

您可能希望在每个循环中都有一个新的Item。喜欢:

Item* newItem;
while (fscanf(fp, "%X %[^\n]", &code, string) != EOF) {
    newItem = malloc(sizeof *newItem);
    if (!newItem) exit(1);

    if (list->length >= list->capacity) {
        list->capacity *= 2;
        list->items = (Item**)realloc(list->items,   // BTW DONT DO THIS - SEE BELOW
            list->capacity * sizeof(Item*));
    }
    newItem->code = code;
    strcpy(newItem->string, string);
    list->items[list->length++] = newItem;
}

顺便说一句:总是 realloc 指向一个 tmp 指针,例如:

tmp = realloc(....);
if (tmp == NULL)
{
    // error handling
}
else
{
    list = tmp;
}

进一步:在 C 语言中,通常不建议使用 cast malloc/ realloc / calloc。使用sizeof *pointer 而不是sizeof(type) 也很常见

所以而不是:

list->items = (Item**)realloc(list->items, list->capacity * sizeof(Item*));

你可以这样做:

tmp = realloc(list->items, list->capacity * sizeof *tmp);

其中tmplist->items 的类型相同

【讨论】:

  • 还写了一条关于不返回 realloc 的注释。见:Do I cast the result of malloc?(同样适用于realloccalloc
  • @DavidC.Rankin 我已经对此发表了评论,但现在我试图让它更清楚一点。
  • 那我该如何释放我的临时工?
  • @4386427 明白了。我理解原件是复制/粘贴问题,但确保您没有在答案中重复这些做法总是好的。很好的修复。
  • @compolo 你永远不必free (temp)。成功时realloctemp 被分配给您的原始指针,当您释放原始指针时,块将被释放。在realloc 失败时,返回NULL 并且没有分配给temp,原始指针被保留并仍然指向在realloc 调用之前存在的原始块(这就是为什么你从不@ 987654350@ 原始 - 如果失败,则返回 NULL 并且您丢失了对原始内存块的引用)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 2014-04-22
  • 1970-01-01
  • 2019-08-24
  • 2013-03-31
  • 2021-05-22
  • 1970-01-01
相关资源
最近更新 更多