C++:“new”的奇怪行为
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);
打印 Rect(x:0, y:0,宽:800,高: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
在我的游戏循环中,我使用同一行来检查 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;
当我取消注释这两行时,我得到正常结果:
/* 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
。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
为了使用“int 的默认值”,您可以使用值初始化:
否则,不会定义值。
提供更多详细信息:向此结构添加构造函数将是最好的方法,但由于它位于您(我认为)无法修改的第三方库中,因此您可以将其包装在提供默认构造函数的您自己的类中,或使用值初始化。引用C++03 8.5/5,
在您的情况下,SDL_Rect 是一个非联合类类型,没有用户声明的构造函数(此列表中的第二个子句),这意味着对其非静态数据成员执行值初始化,并且每个这些数据成员的 属于“otherwise”子句,并且是零初始化的(定义为“如果 T 是标量类型,则将对象设置为转换为 T 的 0(零)值;”)
In order to make use of the "default value for an int", you can use value initialization:
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,
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;")
如果没有初始化变量,那么它的值是未定义的。堆分配的整数没有默认值。
If you do not initialize a variable then it's value is undefined. There is no default value for heap-allocated integers.
AFAIK,C++ 中的
int
和其他非类类型没有默认值。AFAIK, there are no default values for
int
and other non-class types in C++.在 C++ 中,您必须始终初始化所有变量。
In C++ you must always initialize all your variables.
我认为如果您希望类数据成员初始化为给定值(包括 0),您应该在构造函数中显式分配该值。
IIRC,在调试版本中,MSVC 使用 0xCDCCDCD 模式填充已分配但未初始化的堆空间。
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.
将构造函数放入您的结构中:
Put a constructor in your struct:
如果您希望这些值具有默认值,则必须初始化这些值。当您使用 new SDL_Rect 创建结构体时,您只需分配内存,其中包含的数据只是您分配时堆中此位置的数据,因此这大致是随机的。您可以使用构造函数来初始化变量,因为如果您引用它,编译器会自动创建一个构造函数,即
new SDL_Rect()
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()