9

The program I'm working on crashes sometimes trying to read data at the address 0xCCCCCCCC. Google (and StackOverflow) being my friends I saw that it's the MSVC debug code for uninitialized stack variable. To understand where the problem can come from, I tried to reproduce this behavior: problem is I haven't been able to do it.

Question is: have you a code snippet showing how a pointer can end pointing to 0xCCCCCCCC?

Thanks.

gregseth
  • 12,952
  • 15
  • 63
  • 96
  • 2
    Have you initialized all your pointers to a known value? – In silico Sep 01 '10 at 13:32
  • @In silico +1, I'm not sure what the question here is... – synhershko Sep 01 '10 at 13:38
  • Possible duplicate of [When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete?](https://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-malloc-free-new) – phuclv May 06 '18 at 16:28

4 Answers4

12
int main()
{
    int* p;
}

If you build with the Visual C++ debug runtime, put a breakpoint in main(), and run, you will see that p has a value of 0xcccccccc.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
7

Compile your code with the /GZ compiler switch or /RTCs switch. Make sure that /Od switch is also used to disable any optimizations.

s

Enables stack frame run-time error checking, as follows:

  • Initialization of local variables to a nonzero value. This helps identify bugs that do not appear when running in debug mode. There is a greater chance that stack variables will still be zero in a debug build compared to a release build because of compiler optimizations of stack variables in a release build. Once a program has used an area of its stack, it is never reset to 0 by the compiler. Therefore, subsequent, uninitialized stack variables that happen to use the same stack area can return values left over from the prior use of this stack memory.

  • Detection of overruns and underruns of local variables such as arrays. /RTCs will not detect overruns when accessing memory that results from compiler padding within a structure. Padding could occur by using align (C++), /Zp (Struct Member Alignment), or pack, or if you order structure elements in such a way as to require the compiler to add padding.

  • Stack pointer verification, which detects stack pointer corruption. Stack pointer corruption can be caused by a calling convention mismatch. For example, using a function pointer, you call a function in a DLL that is exported as __stdcall but you declare the pointer to the function as __cdecl.

Michael Stum
  • 177,530
  • 117
  • 400
  • 535
2

I do not have MSVC, but this code should produce the problem and compile with no warnings.

In file f1.c:

void ignore(int **p) { }

In file f2.c:

void ignore(int **p);
int main(int c, char **v)
{
  int *a;
  ignore(&a);
  return *a;
}

The call to ignore makes it look like a might be initialized. I doubt the compiler will warn in this case, because of the risk that the warning might be a false positive.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • 1
    In both Visual C++ 2008 and 2010 this exact code generates level 1 warning C4700: "uninitialized local variable 'a' used." You would need to have `ignore` take a pointer or reference to `int*` in order for there to be any chance that `a` is initialized by the call to `ignore`. – James McNellis Sep 01 '10 at 13:38
  • Can you explain the risk of a false positive? – Tomas Sep 01 '10 at 13:43
  • No warning and no 0xCC... addres on my computer. Is there special compilation options to enable the feature? – gregseth Sep 01 '10 at 13:46
  • @James McNellis @Tomas Thanks for pointing this out. I meant of course `ignore (&a);` so that it looks like `ignore()` might initialize `a`. – Pascal Cuoq Sep 01 '10 at 13:48
  • 1
    @gregseth Well, writing `0xCCCCCCCC` all over the stack is expensive, so that may only be enabled by MSVC for debug builds. I have to admit that I do not know more than what is in your question. – Pascal Cuoq Sep 01 '10 at 13:50
  • @gregseth I have changed the assignment into a `return`. The compiler might optimize an assignment away (optimizations that remove undefined behaviors are allowed, because undefined behavior can be anything, even working normally). – Pascal Cuoq Sep 01 '10 at 13:58
  • @gregseth: Visual C++ has a lot of settings for warnings. You'll find them (in VS2008 anyway) under the General and Advanced subtabs of the C/C++ tab of the Property Pages dialog. If somebody else set the project up, there's no telling what they are. – David Thornley Sep 01 '10 at 14:03
0

How about this? Ignore the warning that VC throws while running.

struct A{
    int *p;
};

int main(){
    A a;
    cout << (void *)a.p;
}
Chubsdad
  • 24,777
  • 4
  • 73
  • 129