在C中访问传递的struct数组的成员

时间:2014-04-17 01:09:01

标签: c arrays pointers struct

我有一个方法levenshtein,它填充struct的w / info的2D数组,并返回指向该数组的指针。当我将它发送到另一个方法时,我在运行时遇到Segmentation Fault (core dumped)错误。请帮我这个希望明显的错误。

struct chartEntry
{
    int num;
    bool left,
         up,
         diag;
};

struct chartEntry** levenshtein(char *s1, char *s2, bool toPrint)
{
    unsigned int s1Len,
                 s2Len,
                 i, //rows, general purpose index
                 j; //columns, general purpose index
    s1Len = strlen(s1);
    s2Len = strlen(s2);

    /***********************************
    Create and populate traceback chart
    ***********************************/
    struct chartEntry chart [s1Len+1][s2Len+1];

    //
    // code to populate chart here
    //

    //prints expected number
    printf("chart[3][3].num is %d", chart[3][3].num);
    return chart;
}

void testFunction(char*s1,char*s2)
{
    // both of these give segmentation faults
    printf("[3][3].num is %d", levenshtein(s1,s2,false)[3][3].num);

    struct chartEntry ** tmp = levenshtein(s1,s2,false);
    printf("[3][3].num is %d", tmp[3][3].num);
}

2 个答案:

答案 0 :(得分:2)

这里有2个问题。首先,chart是一个数组数组。这不能转换为指向指针的指针。数组和指针是不同的。你的行return chart;必须给你一个你不应该忽略的编译错误。

其次,即使它可以被转换,chart的内存对于levenshtein函数是本地的,并且在该函数返回时将不再存在。所以你会返回一个狂野的指针。

您有两种选择:

  • 使用chartmalloc分配内存,并返回指向该内存的指针(一个大块或两个间接层)
  • 让调用者分配数组,levenshtein函数只是将值写入其中。

如果您使用第一个选项,那么您不应该像printf中第一次那样使用testFunction,因为内存不会被释放。您必须保存返回的指针,打印它,然后执行free序列,该序列与您用于分配它的malloc序列相反。

答案 1 :(得分:0)

在您的代码中,您尝试返回指向函数内声明的数组的指针:

struct chartEntry** levenshtein(char *s1, char *s2, bool toPrint)
{
    // ...

    struct chartEntry chart [s1Len+1][s2Len+1];

    // ...

    return chart;
}

但是,只要程序退出此函数,该数组就会超出范围并被销毁,从而使指针指向无效的内存。这会导致未定义的行为:也许它有效,也许它不会,也许它会让你的计算机着火。好吧,最后一个不太可能,但关键是,任何事情都可能发生

有两种方法可以解决这个问题:

  • 在调用函数之前创建静态数组,然后在函数调用中将指针传递给此数组。

  • 在函数中动态分配内存,然后可以将其作为普通指针返回。 (调用函数必须确保在使用后释放内存,否则这可能会导致内存泄漏,这是一件坏事,坏事。)