0

I have read through many of the previous posts on C4700, but I can't seem to find a solution to my problem.

I have a little script written to demonstrate struct pointers:

struct foo
{
    int * bar;
};

#include<iostream>
using namespace std;
int main()
{
    foo * fooptr;
    int * num;
    *num = 25;
    *fooptr->bar = *num;
    cout << "now fooptr points to a foo struct whose bar points to: " << *fooptr->bar;

    fooptr->bar = num;
    cout <<"now fooptr's struct's bar shares memory address with num at " <<num;

    return 0;
}

When I compile it, I get two C4700 warnings for uninitialized local variables num and fooptr used. I went ahead and initialized both to NULL, so the compiler error went away but not surprisingly I got an exception:

Unhandled exception at 0x00265DF7 in testing.exe: 0xC0000005: Access violation writing location 0x00000000.

You see I always thought that when I don't initialize those pointers, they'll be automatically initialized with random addresses (just like uninitialized ints/chars/doubles will be assigned garbages)--so shouldn't that be the case here?

If initialization in this case is indeed absolutely necessary (why?), then is there an easy workaround for this problem?

Yibo Yang
  • 2,353
  • 4
  • 27
  • 40
  • I recommend reading a book: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Galik Nov 17 '14 at 00:42
  • I've read and worked through Starting Out With C++, but I guess one book just isn't enough :( – Yibo Yang Nov 17 '14 at 00:48
  • 3
    Where should `*num = 25` put 25 in memory if it is a random address? What if it randomly points to a critical area of your operating system? There is no workaround as what you are doing is fundamentally flawed. You shouldn't write data to somewhere without knowing where it is. – Neil Kirk Nov 17 '14 at 00:49
  • @YiboYang You need to continually reference your books until you remember how all the pieces work (I still reference books). You might want to re-read **Chapter 9** in your book but I still suggest getting books from the recommended list: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Galik Nov 17 '14 at 01:28
  • Agreed. Personally I think the compiler should be designed smart enough to just know how to dynamically allocate memory for uninitialized variables... – Yibo Yang Nov 17 '14 at 01:43
  • Then it would have to check every time you use a pointer if it has been initialized yet and if not, allocate new memory (and who would free it?). That would be slow and allow potentially mistaken code to work fine. – Neil Kirk Nov 17 '14 at 01:56
  • @YiboYang: That would lead to a lot of difficult to find errors. There are multiple ways to allocate memory, how do you expect the compiler to know which one you want to use? This really shouldn't be a problem though, because you have no reason to use pointers here at all. – Benjamin Lindley Nov 17 '14 at 01:58

3 Answers3

4

Instead of

int *num; // num points to somewhere random
*num = 25; // writing somewhere random makes zero sense
           // and if your OS allowed you to do it, you would
           // crash your computer very often.

you must write

int num = 25;
int *pnum = &num; // pnum is a pointer to int which has been
                  // initialized with the address of num

And the same thing applies the struct's content.

jrsala
  • 1,899
  • 12
  • 13
3

Uninitialized variables are not initialized to random values, they are uninitialized. On a machine code level, they have whatever value was there when they were created. This may or may not be the address of an actual object. Either way, it is undefined behavior to try to access an uninitialized pointer value as if there is an object at that address.

So, your compiler is doing you a favor by issuing a warning (it is not required to do so), because your code has undefined behavior.

then is there an easy workaround for this problem?

Set your pointers to point to valid objects before dereferencing them. If you don't, then there are no promises about what behavior your program will have.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • Thanks Ben, that was helpful. I guess I'm still confused on when "new" objects are automatically created versus situations where I have to manually create them. To fix this problem, I initialized fooptr and num dynamically: foo * fooptr = new foo; int * num = new int; Things seem to be working fine, but when I get to line 13, the assignment, *fooptr->bar = *num, I get "Unhandled exception at 0x00AD5E1E in testing.exe: 0xC0000005: Access violation writing location 0xCDCDCDCD." I tried " *(fooptr->bar) = *num ", and " *fooptr->bar = 25 ", but kept getting the same error. What went wrong? – Yibo Yang Nov 17 '14 at 01:39
  • @YiboYang: When you say `*fooptr->bar`, you are dereferencing `bar`. That is, you are trying to get the int which `bar` points to. But `bar` doesn't point to anything, because you never initialized it. You need something like this: `fooptr->bar = new int;`. After that, you can do any of those things you listed. – Benjamin Lindley Nov 17 '14 at 01:44
1

C4700 is not an error. DOT. But MSVC fails to compile on C4700 which is an error because the "/sdl" compiler switch is on by default C4700 discution on visualstudio site , MSDN /sdl switch for vs 2012+

Bretzelus
  • 325
  • 2
  • 8