简体   繁体   中英

Accessing members of a passed struct array in C

I have a method levenshtein that populates a 2D array of struct sw/ info and returns a pointer to that array. When I send it to another method, I get a Segmentation Fault (core dumped) error at runtime. Please help me w/ this hopefully obvious error.

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);
}

There's 2 problems here. Firstly, chart is an array of arrays. This cannot be converted to a pointer-to-a-pointer. Arrays and pointers are different. Your line return chart; must give you a compilation error which you should not ignore.

Secondly, even if it could be converted, chart 's memory is local to the levenshtein function and will no longer exist when that function returns. So you would be returning a wild pointer.

You have two options:

  • allocate memory for chart using malloc and return a pointer to that (either one large block, or with two levels of indirection)
  • have the caller allocate the array and the levenshtein function just writes values into it.

If you use the first option then you should not use the printf as you have done the first time in testFunction , because the memory would not be freed. You have to save the returned pointer, printf it, and then execute a sequence of free that is the reverse of the malloc sequence you used to allocate it.

In your code, you're trying to return a pointer to an array that's declared inside the function:

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

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

    // ...

    return chart;
}

However, as soon as the program exits this function, this array falls out of scope and is destroyed, leaving you with a pointer pointing to invalid memory. This leads to undefined behavior : Maybe it works, maybe it doesn't, maybe it puts your computer on fire. Okay, that last one is pretty unlikely, but the point is, anything can happen .

There are two ways to deal with this problem:

  • Create a static array before calling the function, and then pass a pointer to this array in the function call.

  • Dynamically allocate memory in the function, which can then be returned as a normal pointer. (The calling function has to make sure the memory is freed after use, though, otherwise this may lead to memory leaks, which is a bad, bad thing.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM