C++:“新”的奇怪行为`

C++:“新”的奇怪行为`,c++,types,heap,new-operator,sdl,C++,Types,Heap,New Operator,Sdl,SDL为我提供了以下结构: typedef struct SDL_Rect { Sint16 x, y; Uint16 w, h; } SDL_Rect; 我想在堆上创建一个新的SDL_Rect作为类变量: // Forward declaration private: SDL_Rect *m_pcScreenRect; 在构造函数中,我这样做: /* Screen Rectangle (for clearing) */ m_pcScreenRect = new SD

SDL为我提供了以下结构:

typedef struct SDL_Rect {
    Sint16 x, y;
    Uint16 w, h;
} SDL_Rect;
我想在堆上创建一个新的SDL_Rect作为类变量:

// Forward declaration
private:
    SDL_Rect *m_pcScreenRect;
在构造函数中,我这样做:

/* 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);
它可以打印Rectx:0,y:0,w:800,h:600 所以这是正确的

问题1 但当我不初始化x和y时,它会打印垃圾数字,如:

 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, ....
我认为int的默认值是0

问题2 在我的gameloop中,我用同一行检查SDL_Rect的值。在循环中,我得到如下结果:

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....
/* 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;
当我的构造函数如下所示时:

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....
/* 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;
当我取消注释这两行时,我会得到正常的结果:

/* 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;
这个问题是否与new或数据类型Uint16以及普通int有关。如果是与数据类型有关,如何解决它

非常感谢!哈哈

谢谢, 任何帮助都将不胜感激

额外问题: 我必须在C++中定义所有的变量。 但是随机数是从哪里来的呢


我在Linux中使用g++和gcc.< /p> AFAIK,在C++中没有int值和其他非类类型的默认值。C++中没有int值和其他非类类型的默认值。C++中的

必须始终初始化所有变量。C++中的

必须始终初始化所有变量。

如果不初始化变量,则其值未定义。堆分配的整数没有默认值。

如果不初始化变量,则其值未定义。堆分配的整数没有默认值。

我认为,如果希望将类数据成员初始化为包含0的给定值,则应该在构造函数中显式分配该值


IIRC,在调试构建中,MSVC使用0xCDCDCD模式填充已分配但未初始化的堆空间。

我认为,如果希望将类数据成员初始化为包含0的给定值,则应该在构造函数中显式分配该值


IIRC,在调试版本中,MSVC使用0xCDCDCD模式填充已分配但未初始化的堆空间。

为了使用int的默认值,可以使用值初始化:

m_pcScreenRect = new SDL_Rect(); // this will initialize to zeros
否则,将不定义值

提供更多细节:将构造函数添加到此结构中是最好的方法,但由于它位于第三方库中,我认为您无法修改它,因此您可以将其包装在您自己的类中,该类提供默认构造函数,或者使用值初始化。引用C++038.5/5

初始化T类型对象的值意味着:

如果T是具有用户声明的构造函数的类类型,则调用T的默认构造函数

如果T是没有用户声明构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都被初始化

如果T是数组类型,则每个元素都初始化为值

否则,对象初始化为零


在您的例子中,SDL_Rect是一个非联合类类型,在此列表中没有用户声明的构造函数second子句,这意味着对其非静态数据成员执行值初始化,并且这些数据成员中的每个都属于otherwise子句,并且初始化为零,这被定义为T是标量类型,将对象设置为0 0的值,并转换为T

为了使用int的默认值,可以使用值初始化:

m_pcScreenRect = new SDL_Rect(); // this will initialize to zeros
否则,将不定义值

提供更多细节:将构造函数添加到此结构中是最好的方法,但由于它位于第三方库中,我认为您无法修改它,因此您可以将其包装在您自己的类中,该类提供默认构造函数,或者使用值初始化。引用C++038.5/5

初始化T类型对象的值意味着:

如果T是具有用户声明的构造函数的类类型,则调用T的默认构造函数

如果T是没有用户声明构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都被初始化

如果T是数组类型,则每个元素都初始化为值

否则,对象初始化为零


在您的例子中,SDL_Rect是一个非联合类类型,在此列表中没有用户声明的构造函数second子句,这意味着对其非静态数据成员执行值初始化,并且这些数据成员中的每个都属于otherwise子句,并且初始化为零,这被定义为T是标量类型,将对象设置为0 0的值,并转换为T

在结构中放置构造函数:

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

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

在结构中放置构造函数:

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

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

如果希望值具有默认值,则必须初始化这些值。当您使用新的SDL_Rect创建一个结构时,您只需分配内存,其中包含的数据就是您分配时在堆的这个位置的数据,因此这大致是随机的。你可以用co
构造函数初始化变量,因为如果引用它,编译器会自动创建一个变量,即新的SDL_Rect,如果希望值具有默认值,则必须初始化值。当您使用新的SDL_Rect创建一个结构时,您只需分配内存,其中包含的数据就是您分配时在堆的这个位置的数据,因此这大致是随机的。您可以使用构造函数初始化变量,因为如果您引用它,编译器会自动创建一个,即new SDL_Rect

@Cubbi:那么diff是?这个diff有名字吗?我想了解它。@Martijn名称是值初始化或值初始化。这是C++98和C++03之间的主要区别。@Martijn:内置有区别。如果我没记错的话,试着用谷歌搜索一下值初始化和默认初始化。这不是一个默认构造函数吗?@Michael:SDL\u Rect是一个POD,它只有内置的,没有构造函数。对于这样的类型,默认构造和值初始化或任何正确的术语之间都有区别。@Cubbi:那么diff是正确的吗?这个diff有名字吗?我想了解它。@Martijn名称是值初始化或值初始化。这是C++98和C++03之间的主要区别。@Martijn:内置有区别。如果我没记错的话,试着用谷歌搜索一下值初始化和默认初始化。这不是一个默认构造函数吗?@Michael:SDL\u Rect是一个POD,它只有内置的,没有构造函数。对于这样的类型,默认构造和值初始化或任何正确的术语之间都有区别。是的,这是正确的,但不需要对所有类型都显式地这样做。如果一个类有一个std::string成员,那么它也将被隐式初始化。这是因为std::string有一个构造函数,int、char、float等等。是的,这是正确的,但不需要对所有类型都显式初始化。如果一个类有一个std::string成员,那么它也将被隐式初始化。这是因为std::string有一个构造函数,int、char、float等都没有。@dbemerlin:还有其他人,谢谢你提供的信息。为你们所有人+1!第一句话并非普遍正确。用户定义的类型将为您隐式初始化:struct X{std::string m;};X@德贝默林:还有其他人,谢谢你提供的信息。为你们所有人+1!第一句话并非普遍正确。用户定义的类型将为您隐式初始化:struct X{std::string m;};X;。但是,结构X{std::string m;X{};很好。它只是内置的,没有进行隐式初始化;很好。它只是内置的,没有进行隐式初始化。随机数来自新变量分配到的内存位置。他们得到以前在这个地方的任何价值。简化示例:如果您分配一个100字节的数组,给它们分配一些值,释放它,并分配一个25整数的数组4字节整数。精确地说,它们可能会根据许多因素获得先前分配的100字节中的4个字节,并获取这些字节在释放时的值。如果前4个字节为0x00010203,则结果整数将为66051,除非您显式初始化它。随机数来自新变量分配到的内存位置。他们得到以前在这个地方的任何价值。简化示例:如果您分配一个100字节的数组,给它们分配一些值,释放它,并分配一个25整数的数组4字节整数。精确地说,它们可能会根据许多因素获得先前分配的100字节中的4个字节,并获取这些字节在释放时的值。如果前4个字节为0x00010203,则结果整数将为66051,除非您以其他方式显式初始化它。