简体   繁体   中英

Run-Time Check Failure #2 - Stack around the variable 'obj' was corrupted

I am getting Run-Time Check Failure #2 - Stack around the variable 'obj' was corrupted error when I run the following code. I know this is failing because of overwriting the bounds of 'obj' causing corrupting the stack. So how to prevent buffer overrun here.

typedef struct _INFO {
    int Count;
} Info, *InfoPtr;

#define MAX_COUNT               10

//void fn(Info(*obj)[MAX_COUNT])
void fn(Info (*obj)[MAX_COUNT])
{
    for (int i = 0; i < 2; i++) 
    {
        obj[i]->Count = i;
    }
}

int main()
{
    Info    obj[MAX_COUNT];
    fn(&obj);
    return 1;
}

With Info (*obj)[MAX_COUNT] you say that obj is a pointer to an array of MAX_COUNT objects of type Info .

But then you use it like obj[i]->Count = i which treats obj as an array of pointers to Info objects. Ie Info *obj][] . Not the same thing. And that leads to undefined behavior .

The solution is quite simple, don't pass a pointer to the array as argument, and treat it as an array of objects and not pointers to objects.

Ie

typedef struct Info {
    int Count;
} Info;

#define MAX_COUNT               10

void fn(Info *obj, const size_t elems)
{
    for (size_t i = 0; i < elems; i++) 
    {
        obj[i].Count = i;
    }
}

int main()
{
    Info    obj[MAX_COUNT];
    fn(obj, MAX_COUNT);
}

The changes are most notably the fn function declaration, which takes a pointer to Info . That is because arrays naturally decays to pointers to their first element. I also added an argument to hold the number of elements in the array, so the function knows it. That makes the function more general and you can pass it different arrays of different sizes.

I also changed to main function to not return anything at all. Since the C99 standard a main function without an explicit return will implicitly get a return 0 by the compiler. And returning 0 from the main function is usually seen as "okay" or "no failure". Returning a non-zero value is considered as a failure or error.

I also changed the name of your structure. Names (C or preprocessor) with a leading underscore followed by an upper-case letter is reserved in all scopes by the compiler and the standard C library. Also, structure tag names live in a separate namespace, so you can have the same name of the structure as a type-name (type-alias, as defined by typedef ). I also removed the InfoPtr type-name, using such pointers as type-names obfuscates the code and makes it less readable and maintainable.

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