why does this code cause a crash only in retail? [closed]
there is obviously issues with this code but it causes an access violation only in retail and not in debug. any specific reasons? VS 2008 is the compiler. assume enabled = true
void parse(bool enabled)
{
char* p开发者_如何学Go = NULL;
if (enabled)
{
char a[100] = 'jsajas';
p = &a;
}
if (p != NULL)
{
p[0] = 'a';
}
}
EDIT: I know the reason why this fails. I wanted to know what is causing it to crash in retail and not in debug. how is the memory handled differently.
EDIT: edited the code slightly to make it more clear what my question is.
EDIT: reverting the old code and adding the new code below as people dont seem to like it. Sorry for causing confusion. My intention is to really understand the issue when allocated in the heap.
void parse(bool enabled)
{
char* p = NULL;
if (enabled)
{
char* a = new char[100];
a[0] = 'a';
p = a;
}
if (p != NULL)
{
p[0] = 'a';
}
}
You are accessing a variable (the array a
) after the flow of control has exited the scope in which it is declared. This is undefined behaviour.
MSVC can generate very different code depending on whether you are using a Release or Debug set of switches. It's possible that:
- in Debug mode, the compiler allocates enough space on the stack for all variables declared anywhere within the function
- in Release mode, the compiler generates code that changes the amount of memory allocated on the stack as scopes are entered and exited
In order to find the answer, you can look at the generated assembly code.
Statement should be p = a;
an array is already a pointer you're telling p to be a pointer of a pointer which is why you're accessing some odd memory location. On top of this array a is declared inside the a scope, this is undefined, some compilers preallocate this and it will work fine, others declare it only once executing inside the scope of the if statement.
Should be char a[100] = "abcd"
(note double quotes)
Should be p = a
or p = &a[0]
And of course, as soon as a
goes out of scope at the first }
, the array object is no longer valid. So this is Undefined Behavior, which can easily work fine with one compiler, compiler version, or set of switches and crash with another.
Undefined behavior is undefined. It may crash, trash the stack, or just proceed normally. There's no rhyme or reason to it, because it's undefined. It can do different things in different builds; there's no guarantee of anything. Hence the term "undefined".
That's why you should stick with defined behavior.
void parse(bool enabled)
{
char* p = NULL;
if (enabled)
{
char* a = new char[100];
a[0] = 'a';
p = a;
}
if (p != NULL)
{
p[0] = 'a';
}
}
Your modified piece of codes looks fine. But you did not free the 100 bytes allocated from the heap. And the pointers (both a and p) pointing to the allocated memory is not known outside of this function. It means no one outside of this function can de-allocate too.
Memory leak.
精彩评论