Martijn Courteaux
Martijn Courteaux

Reputation: 68847

C++: Strange behaviour of `new`

SDL provides me this struct:

typedef struct SDL_Rect {
    Sint16 x, y;
    Uint16 w, h;
} SDL_Rect;

I want to create a new SDL_Rect on the heap as class variable:

// Forward declaration
private:
    SDL_Rect *m_pcScreenRect;

And in the constructor I do this:

/* Screen Rectangle (for clearing) */
m_pcScreenRect = new SDL_Rect;
m_pcScreenRect->x = 0;
m_pcScreenRect->y = 0;
m_pcScreenRect->w = 800;
m_pcScreenRect->h = 600;
printf("Rect(x:%d, y:%d, w:%d, h:%d)\n", m_pcScreenRect->x, m_pcScreenRect->y, m_pcScreenRect->w, m_pcScreenRect->h);

Which prints Rect(x:0, y:0, w:800, h:600)
So this is correct.

Problem 1

But when I don't initialize x and y, it prints rubbish numbers like:

 Rect(x:-11280, y:63, w:800, h:600)
 Rect(x:25584, y:167, w:800, h:600)
 Rect(x:-11280, y:40, w:800, h:600)
 // This is just, run, terminate, run, terminate, ....

And I thought the default value for an int is 0?

Problem 2

In my gameloop, I have the same line to check the values of the SDL_Rect. In the loop I get results like this:

Clear (x:0, y:40, w:0, h:560)
Clear (x:0, y:99, w:0, h:501)
Clear (x:0, y:55, w:0, h:545)
Clear (x:0, y:55, w:0, h:545)
// Again: run, terminate, run, terminate....

When my constructor looks like this:

/* Screen Rectangle (for clearing) */
m_pcScreenRect = new SDL_Rect;
//m_pcScreenRect->x = 0;
//m_pcScreenRect->y = 0;
m_pcScreenRect->w = 800;
m_pcScreenRect->h = 600;

And I get normal results when I uncomment the two lines:

/* Screen Rectangle (for clearing) */
m_pcScreenRect = new SDL_Rect;
m_pcScreenRect->x = 0;
m_pcScreenRect->y = 0;
m_pcScreenRect->w = 800;
m_pcScreenRect->h = 600;

Does this problem something have to do with new or with the datatypes (Uint16, and a normal int). If it is with the datatypes, how to solve it?

Thanks would be very appreciated! (Haha!)

Thanks,
Any help would be very appreciated!


Extra Question:

I have to define all my variables in C++.
But from where do the random numbers come?

I'm using g++ and gcc in Linux.

Upvotes: 1

Views: 332

Answers (7)

Cubbi
Cubbi

Reputation: 47418

In order to make use of the "default value for an int", you can use value initialization:

m_pcScreenRect = new SDL_Rect(); // this will initialize to zeros

Otherwise, the values are not defined.

To give more details: adding a constructor to this structure would be the best approach, but since it's in a third-party library which you (I suppose) cannot modify, you can either wrap it in your own class that provides a default constructor, or use value-initialization. To quote C++03 8.5/5,

To value-initialize an object of type T means:

  • if T is a class type with a user-declared constructor, then the default constructor for T is called

  • if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;

  • if T is an array type, then each element is value-initialized;

  • otherwise, the object is zero-initialized

In your case, SDL_Rect is a non-union class type without a user-declared constructor (second clause in this list), meaning value-initialization is performed for its non-static data memebers, and each of those data members falls under the "otherwise" clause, and is zero-initialized (which is defined as "if T is a scalar type, the object is set to the value of 0 (zero) converted to T;")

Upvotes: 5

slaphappy
slaphappy

Reputation: 6999

You have to initialize the values if you want them to have a default value. When you create a struct using new SDL_Rect, you just allocate the memory and the data contained in it is just the data which where at this place of the heap when you allocated, so this is roughly random. You can use a constructor to initialize the variables since the compiler automatically creates one if you reference it, i.e. new SDL_Rect()

Upvotes: 0

Adrian Regan
Adrian Regan

Reputation: 2250

Put a constructor in your struct:

typedef struct SDL_Rect {
    SDL_Rect() { x = 0; y = 0; w = 0; h = 0; }

    Sint16 x, y;
    Uint16 w, h;
} SDL_

Upvotes: 0

EmbeddedProg
EmbeddedProg

Reputation: 877

I think if you want your class data members to be initialized to a given value (including 0), you should just explicitly assign that in the constructor.

IIRC, in debug builds, MSVC fills allocated but uninitialized heap space with 0xCDCDCDCD pattern.

Upvotes: 1

user253984
user253984

Reputation:

If you do not initialize a variable then it's value is undefined. There is no default value for heap-allocated integers.

Upvotes: 3

danatel
danatel

Reputation: 4982

In C++ you must always initialize all your variables.

Upvotes: 1

swegi
swegi

Reputation: 4102

AFAIK, there are no default values for int and other non-class types in C++.

Upvotes: 2

Related Questions