【问题标题】:Program crashes when calling new operator (C++)调用新运算符时程序崩溃(C++)
【发布时间】:2013-07-04 19:54:53
【问题描述】:

我正在学习我找到的一些关于用 C 创建 ASCII 游戏引擎和用 C++ 编写程序来练习的教程。我目前正在处理一些东西,以 Image 结构的形式在堆上分配图像数据(包含一个 int 宽度、int 高度和两个 char 指针,指向堆上保存字符数组 [width * height] 的位置size)... 但是,我在调用 new 运算符时遇到了一些问题。我为结构本身及其字符和颜色数据分配内存的函数如下所示:

Image *allocateImage(int width, int height) {

Image *image;
image = new Image;

if (image == NULL)
    return NULL;

image->width = width;
image->height = height;
image->chars = new CHAR[width * height];
image->colours = new COL[width * height];

//image->colours = (CHAR*) PtrAdd(image->chars, sizeof(CHAR) + width * height);

for (int i = 0; i < width * height; ++i) { //initializes transparent image
    *(&image->chars + i) = 0;
    *(&image->colours + i) = 0;
}
return image;
}

主函数本身(该函数被调用两次)如下所示:

int main() {
int x, y, offsetx, offsety;

DWORD i;

srand(time(0));

bool write = FALSE;

INPUT_RECORD *eventBuffer;

COLORREF palette[16] =
  {
        0x00000000, 0x00800000, 0x00008000, 0x00808000,
        0x00000080, 0x00800080, 0x00008080, 0x00c0c0c0,
        0x00808080, 0x00ff0000, 0x0000ff00, 0x00ffff00,
        0x000000ff, 0x00ff00ff, 0x0000ffff, 0x00ffffff
  };

COORD bufferSize = {WIDTH, HEIGHT};

DWORD num_events_read = 0;

SMALL_RECT windowSize = {0, 0, WIDTH - 1, HEIGHT - 1};

COORD characterBufferSize = {WIDTH, HEIGHT};
COORD characterPosition = {0, 0};
SMALL_RECT consoleWriteArea = {0, 0, WIDTH - 1, HEIGHT - 1};

wHnd = GetStdHandle(STD_OUTPUT_HANDLE);
rHnd = GetStdHandle(STD_INPUT_HANDLE);

SetConsoleTitle("Title!");
SetConsolePalette(palette, 8, 8, L"Sunkure Font");

SetConsoleScreenBufferSize(wHnd, bufferSize);
SetConsoleWindowInfo(wHnd, TRUE, &windowSize);

for (y = 0; y < HEIGHT; ++y) {
    for (x = 0; x < WIDTH; ++x) {
        consoleBuffer[x + WIDTH * y].Char.AsciiChar = (unsigned char)219;
        consoleBuffer[x + WIDTH * y].Attributes = FOREGROUND_BLUE;
    }
}

write = TRUE;

Image *sun_image = allocateImage(SUNW, SUNH);
Image *cloud_image = allocateImage(CLOUDW, CLOUDH);
setImage(sun_image, SUN.chars, SUN.colors);
setImage(cloud_image, Cloud.chars, Cloud.colours);

如果有人觉得有必要,我可以发布更多代码,但程序只能达到这一点 - 事实上,就在不久之前,因为它在第二次调用 allocateImage 时崩溃,在函数中新运算符所在的点叫。到目前为止,该程序一直运行良好 - 最近添加的唯一功能是在堆上分配图像数据(用于创建可变大小的图像)以及解除分配(该程序未达到) .由于我正在学习的程序是用 C 语言编写的,因此查看源代码对我没有帮助,而且 Google 也没有太大帮助。谁能指出我出了什么问题?

【问题讨论】:

  • 图像* image = new Image(); (添加括号) - 初始化逻辑看起来也很可疑,除非 COL 是原始类型。
  • 当没有参数时,括号是可选的。
  • 抱歉,应该添加这些定义 - CHAR 和 COL 都定义为无符号字符。
  • 发布您的 Image 类的代码(它的 ctor 应该负责您在 allocateImage 中所做的大部分事情,但一旦您使用它就可以修复)
  • 1. allocateImage 应该是构造函数。 2.不返回指针,返回对象。 3. 不要在new 之后检查NULL,它没用(new永远返回NULL)。无论如何,您并没有始终如一地这样做。 4.Don’t use pointers, use C++ data structures.

标签: c++ new-operator


【解决方案1】:

这些行

*(&image->chars + i) = 0;
*(&image->colours + i) = 0;

是可疑的,因为image 已经是一个指针。指向指针的指针在这里没有意义。只需删除&amp;

由于您的实际代码写入乔随机地址,任何事情都可能发生。因此,您阻止内存子系统并因此阻止下一个 new 调用并不罕见。

【讨论】:

  • 更清楚的是将其更改为数组表示法,就像您在其他地方所做的那样,例如:image->chars[i] = 0;
  • 工作,谢谢!我什至不能 100% 确定我为什么会在那里 - 我一看到它就很清楚出了什么问题,但是当我自己看时却没有看到它 =/
  • @CommanderCorianderSalamander:请随意接受这个答案 :-)
  • 完成!不太习惯 StackOverflow,这是我第一次发问题 ​​;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
  • 2016-03-20
相关资源
最近更新 更多