C++动态数组大小

C++ dynamic array size

本文关键字:数组 动态 C++      更新时间:2023-10-16

所以我目前正在阅读有关光线追踪的信息,并想为自己测试一些东西,看看我是否理解这些概念。我查找了如何从 http://netpbm.sourceforge.net/doc/ppm.html 编写一个简单的 ppm 文件。

我正在使用Visual Studio 2015并将每个像素的rgb值存储在2D数组中。图像的分辨率为 720p,每个像素有 3 个整数,分别是红色、绿色和蓝色,所以我制作的数组看起来像int[720*1280][3]

我计算出内存的总使用量应该是 4 字节(对于指向 2D 数组的指针)+ 720*1280*(4+3*4) 字节(对于 720*1280 个指针,每个指针指向一个具有 3 个整数的数组),大约是 14mb。

当我在视觉工作室中检查内存使用情况时,它说它使用了大约 60mb 的内存。我想问的是,额外的36 mb从何而来?

主.cpp

#include <iostream>
#include "PPM.h"

int main(int argc, char **argv)
{
// WIDTH AND HEIGHT OF THE IMAGE
const int width = 1280;
const int height = 720;
// 3 RGB VALUES FOR EACH PIXEL
const int rgb = 3;
// CREATE A BUFFER TO HOLD THE DATA
int **data = allocateBuffer(width, height, rgb);
// FILL IN THE BUFFER
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
data[y*width + x][0] = x %255;
data[y*width + x][1] = y %255;
data[y*width + x][2] = 0;
}
}
// WRITE THE DATA TO A FILE
saveImage("Test.ppm", width, height, data);
// DELETE THE BUFFER
deleteBuffer(data, width*height);
// WAIT FOR INPUT TO EXIT
std::cout << "Press ENTER key to exitn";
std::getchar();
return 0;
}

PPM.h

#pragma once
// WRITES THE DATA TO THE FILE
extern void saveImage(char *filename, int width, int height, int **data);
// CREATES A BUFFER TO HOLD THE DATA
extern int** allocateBuffer(int width, int height, int rgbAmnt);
// RELEASES THE MEMORY
extern void deleteBuffer(int **buffer, int size);

PPM.cpp

#include "PPM.h"
#include <fstream>
// WRITES THE DATA TO THE FILE
void saveImage(char *filename, int width, int height, int **data)
{
std::ofstream file;
file.open(filename);
file << "P3" << "n" << width << " " << height << "n255n";
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
file << data[y*width + x][0] << " " << data[y*width + x][1] << " " << data[y*width + x][2] << "n";
}
}
file.close();
}
// CREATES A BUFFER TO HOLD THE DATA
int** allocateBuffer(int width, int height, int rgbAmnt)
{
int size = width * height;
int **data = new int*[size];
for (int i = 0; i < size; i++)
{
data[i] = new int[rgbAmnt];
}
return data;
}
// RELEASE THE MEMORY
void deleteBuffer(int **buffer, int size)
{
for (int i = 0; i < size; i++)
{
delete[] buffer[i];
}
delete[] buffer;
}

简而言之,当您要求内存块时,您通常会得到比您要求的更多。即使你不知道。

发生这种情况有几个原因。以下是其中的一些:第一,为了性能:如果内存块沿某些边界对齐,则多个处理器将运行得更快,这意味着块地址是某个整数的倍数(通常是 2 的幂);第二,对于粒度,意味着较低级别的软件(操作系统和程序的运行时库)更喜欢管理最小大小的块;第三个用于内存本身的管理,这意味着较低级别的软件将在您的数据块中添加标头(前缀)和可能的尾部(或后缀)。他们将拥有允许分配和释放这些数据块的信息,也许还有一些验证。

例如,分配的数据块的大小、指向下一个块的指针以及标头和尾部的校验和,以确保它们不会被粗心或恶性程序损坏。