【问题标题】:ptr*** not workingptr*** 不工作
【发布时间】:2011-09-11 08:52:15
【问题描述】:

代码在 main 的第二个 for 循环中必须通过 c.foos 访问 foo 元素时无法正常工作(段错误)。

它只正确显示第一个元素,然后在 i=1 时显示垃圾,并在 i=2 时最终崩溃。

所以我猜它与指针数学有关。

如何正确操作?不允许更改数据结构(不,这不是功课,这是this 数据结构的过度简化的POC)。

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

typedef struct _foo {
    int i;
} foo;

typedef struct _foo_container {
    foo ***foos;
} container;

foo** init_foos(void) {
    foo** f;
    int i;

    f = malloc(sizeof(foo*)*3);

    for(i=0; i < 3; i++) {
        f[i] = malloc(sizeof(foo));
        f[i]->i = i*11+1;
    }
    return f;
}

int main(void) {
    container c;
    foo **foos;

    foos = init_foos();

    c.foos = &foos;
    int i;
    for(i=0; i < 3; i++) {
        printf("%d %d\n", i, foos[i]->i);
    }
    for(i=0; i < 3; i++) {
        printf("%d %d\n", i, (**c.foos[i]).i);
    }
    //memory leaks, I know

    return EXIT_SUCCESS;
}

注意:此代码似乎有效。我猜自上次 gcc 升级以来也发生了一些事情,尽管我可能仍然做错了什么。

附录:抱歉大家错过了*3,我匆忙写了这个POC。实际代码确实通过 php 的 safe_emalloc() 分配了所需指针的数量。

【问题讨论】:

  • s/这段代码曾经工作过/这段代码似乎工作过一次/

标签: c pointers segmentation-fault


【解决方案1】:

试试:

printf("%d %d\n", i, (*(*c.foos)[i]).i);

我认为问题在于运营商precedence。如果您没有为表达式设置父级,则“[]”在“*”之前进行评估。

【讨论】:

  • 即使这修复了您看到的错误,看起来您还有另一个错误需要修复。
  • 是的,这个错误不在实际代码中,我只是匆忙编写了这个 POC。我正在使用 php 的 safe_emalloc(),它也作为参数 nmemb。
【解决方案2】:

init_foo你必须分配3 * sizeof(foo *)

【讨论】:

    【解决方案3】:

    我认为你的问题在这里:

    f = malloc(sizeof(foo*));
    

    看起来你想要的是一个 foo 指针数组,但你只分配了一个 foo 指针。

    尝试将其更改为:

    f = malloc(sizeof(foo*) * 3);
    

    【讨论】:

      【解决方案4】:
      f = malloc(sizeof(foo*));
      

      您正在分配一块大小与指向foo 的指针大小相同的内存。但随后您立即将其索引为f[i]i 最多为 2。因此您正在访问尚未分配的内存。

      【讨论】:

        猜你喜欢
        • 2021-12-26
        • 1970-01-01
        • 2017-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-28
        • 2021-04-06
        相关资源
        最近更新 更多