看来我不太明白什么是 C++ 中的二维(n 维)数组,它们是用于 RAM 的,以及在堆栈上声明的二维数组是这样的:
RGBQUAD frameBuffer[300][300];
不同于动态声明的二维数组:
RGBQUAD ** frame = new RGBQUAD*[height];
for (uint32_t i = 0; i < height; i++)
{
frame[i] = new RGBQUAD[width];
std::fill_n(frame[i], width, clearColor);
}
现在稍微介绍一下任务本身
我决定尝试编写类似software-renderera的东西,我决定从最基本的点开始(即在屏幕上显示它)。在 WinAPI 中,当然有绘制和设置单个像素颜色的工具,但是在对这个主题进行了一些修改后,我意识到正确的做法是将帧准备为位图图像,然后显示此图像在窗户上。也就是说,按照计划,我将形成一个位图,我会以一定的频率将其显示在窗口上,从而得到类似动画的东西。就其本身而言,我所拥有的图片的显示是这样进行的:
// Cоздать временный bitmap (4 байта на пиксель), последний параметр типа void*
// Это может быть как одномерный так и двумерный массив структур RGBQUAD
HBITMAP hBitMap = CreateBitmap(width, height, 1, 8 * 4, pixels);
// Получить device context окна
HDC hdc = GetDC(hWnd);
// Временный DC для переноса bit-map'а
HDC srcHdc = CreateCompatibleDC(hdc);
// Связать bit-map с временным DC
SelectObject(srcHdc, hBitMap);
// Копировать содержимое временного DC в DC окна
BitBlt(
hdc, // HDC назначения
0, // Начало вставки по оси X
0, // Начало вставки по оси Y
width, // Ширина
height, // Высота
srcHdc, // Исходный HDC (из которого будут копироваться данные)
0, // Начало считывания по оси X
0, // Начало считывания по оси Y
SRCCOPY // Копировать
);
// Уничтожить bit-map
DeleteObject(hBitMap);
// Уничтожить временный DC
DeleteDC(srcHdc);
// Уничтожить DC
DeleteDC(hdc);
一切正常,令人惊讶的是,它同时使用一维和二维结构数组作为参数pixels(在函数中CreateBitmap)。好像C ++中没有动态声明的二维数组被视为一维..然后我尝试在堆上动态分配相同的帧缓冲区(二维数组),即事实上,创建一个指向数组的指针数组,这正是我所做的)。最后,一切都停止了工作,现在该功能CreateBitmap不明白这一点。然后我尝试动态分配一个一维数组,如下所示:
RGBQUAD * frame = new RGBQUAD[width * height];
std::fill_n(frame, width * height, clearColor);
一切都立即开始起作用。
问:怎么了?我错过了什么?在 C++ 中动态声明的二维数组是否与以通常方式声明的二维数组不同?有什么区别?提前致谢。
对于普通数组,比如
int a[3]andint b[3][3],只有元素本身在内存中连续存储,仅此而已。这就是使用
new. 指向第一个元素的指针单独存储。对于多维数组,您使用了指向数组的指针数组,也就是“撕裂”数组。
在这种情况下,行不必连续位于内存中,这与以通常方式创建的数组不同,例如
int f[3][4].使行连续进入内存的最方便(在我看来)方法,您已经发现:使用一维数组:
int *g = new int[w * h];。如果您想使用一种方便的语法来访问元素:
g[y][x]而不是g[y * w + x],那么最好使用重载的运算符创建您自己的二维数组类[]。顺便说一句,我强烈建议您使用代替
newand 。deletestd::vector使用 new/delete,很容易忘记释放内存和泄漏。你被折磨着以后再搜索。
如果代码中的某些内容引发异常,则特别容易忘记。
A
std::vector为您监视内存的释放。不同的是静态二维数组和一维数组没有区别,所以在图上会这样定位(二维5x5静态数组的例子)
ロ表示一个单元格并且在动态二维数组中,所有的第一个元素都是指针,并且所有元素都分别位于RAM中(二维动态数组5x5的例子)上图
&表示一个链接因此,它们随机分散在 RAM 中,与静态二维数组不同
如果你想要一个连续的二维数组,有一个选项