C++:“new”的奇怪行为

发布于 2024-09-07 05:41:20 字数 1977 浏览 8 评论 0原文

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

但是当我不初始化 xy 时,它会打印垃圾数字,例如:

 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

慢慢从新开始 2024-09-14 05:41:20

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

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

否则,不会定义值。

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

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

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

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

  • 如果 T 是数组类型,则每个元素都进行值初始化;

  • 否则,对象将被零初始化

在您的情况下,SDL_Rect 是一个非联合类类型,没有用户声明的构造函数(此列表中的第二个子句),这意味着对其非静态数据成员执行值初始化,并且每个这些数据成员的 属于“otherwise”子句,并且是零初始化的(定义为“如果 T 是标量类型,则将对象设置为转换为 T 的 0(零)值;”)

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;")

执手闯天涯 2024-09-14 05:41:20

如果没有初始化变量,那么它的值是未定义的。堆分配的整数没有默认值。

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

秋风の叶未落 2024-09-14 05:41:20

AFAIK,C++ 中的 int 和其他非类类型没有默认值。

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

末が日狂欢 2024-09-14 05:41:20

在 C++ 中,您必须始终初始化所有变量。

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

高速公鹿 2024-09-14 05:41:20

我认为如果您希望类数据成员初始化为给定值(包括 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.

夜吻♂芭芘 2024-09-14 05:41:20

将构造函数放入您的结构中:

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

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

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_
青萝楚歌 2024-09-14 05:41:20

如果您希望这些值具有默认值,则必须初始化这些值。当您使用 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()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文