[英]Setting all points of array to 0 having different effect to reallocating dynamic memory
I am trying to make a something that will draw lines on a pixel grid, then on to a bitmap. 我正在尝试做一些可以在像素网格上绘制线条,然后再绘制到位图上的东西。 I can (pretty much) get my the desired effect by reallocating the memory with 'new' (though the array is to big to delete[] so I end up with a memory leak). 我可以(几乎)通过用'new'重新分配内存来获得我想要的效果(尽管数组对于delete []来说很大,所以最终导致内存泄漏)。
My problem is, that I cannot for the life of me, work out why doing: 我的问题是,我无法为自己的一生而找出为什么这样做:
for (register unsigned int i = 0; i < WIDTH + HEIGHT * 4; i++)
{
previewedPixels[i] = 0;
}
has a different effect than doing 与做事有不同的效果
previewedPixels = new sf::Uint8[WIDTH * HEIGHT * 4];
This is the rest of the code, to put it in perspective (the line that reallocates the memory and causes a memory leak is commented). 这是代码的其余部分,将其放在透视图中(注释了重新分配内存并导致内存泄漏的行)。 Please excuse the mess :p 请原谅:p
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <vector>
#include <iostream>
#define WIDTH 800
#define HEIGHT 600
class element
{
public:
unsigned char value;
unsigned char red;
unsigned char green;
unsigned char blue;
};
const int WIDTHxHEIGHT = WIDTH * HEIGHT;
std::vector< std::vector<short> >XandY(WIDTHxHEIGHT * 2, std::vector<short>(2, 0)); //This is the x and y values for the arrays below
sf::Uint8 *mainPixels = new sf::Uint8[WIDTH * HEIGHT * 4];
sf::Uint8 *previewedPixels = new sf::Uint8[WIDTH * HEIGHT * 4]; //Previewed pixel co- ordinates
sf::Uint8 *pixels = new sf::Uint8[WIDTH * HEIGHT * 4]; //Put the preview and main pixel grids together on this
element *currentElement; //Value of the element currently selected
/*****Declare Elements Here*****/
element metal;
void elementInit()
{
metal.value = 1;
metal.blue = 90;
metal.red = 90;
metal.green = 90;
}
inline void wipe()
{
for (register unsigned int i = 0; i < WIDTH + HEIGHT * 4; i++)
{
previewedPixels[i] = 0;
}
}
inline void draw(short x, short y, unsigned char r, unsigned char g, unsigned char b, bool preview)
{
if (preview)
{
previewedPixels[(x + WIDTH * y) * 4 + 0] = r;
previewedPixels[(x + WIDTH * y) * 4 + 1] = g;
previewedPixels[(x + WIDTH * y) * 4 + 2] = b;
previewedPixels[(x + WIDTH * y) * 4 + 3] = 255;
}
else
{
mainPixels[(x + WIDTH * y) * 4 + 0] = r;
mainPixels[(x + WIDTH * y) * 4 + 1] = g;
mainPixels[(x + WIDTH * y) * 4 + 2] = b;
mainPixels[(x + WIDTH * y) * 4 + 3] = 255;
}
}
void display(void *UserData)
{
}
void lineDraw(short x1, short y1, short x2, short y2, bool preview)
{
short xDiff = std::abs(x1 - x2); //Difference between the two 'x' co-ordinates
short yDiff = std::abs(y1 - y2); //and the two y co-ordinates
unsigned char red, green, blue;
red = currentElement->blue;
green = currentElement->green;
blue = currentElement->blue;
if (xDiff > yDiff && x1 < x2) //Which quadrant it's in. This one is horizontal going right
{
if (preview) //If it is a preview then then put it onto a different array of mainPixels
{
for (short i = x1; i <= x2; i++)
draw(i, y1, red, green, blue, true);
}
else //If it's not a preview then just go ahaid on the normal array
{
for (short i = x1; i <= x2; i++)
draw(i, y1, red, green, blue, false);
}
}
else if (xDiff > yDiff && x1 > x2) //Horizontal going left
{
if (preview)
{
for (short i = x1; i >= x2; i--)
draw(i, y1, red, green, blue, true);
}
else
{
for (short i = x1; i >= x2; i--)
draw(i, y1, red, green, blue, false);
}
}
else if (xDiff < yDiff && y1 > y2) //Going down
{
if (preview)
{
for (short i = y1; i >= y2; i--)
draw(x1, i, red, green, blue, true);
}
else
{
for (short i = y1; i >= y2; i--)
draw(x1, i, red, green, blue, false);
}
}
else if (xDiff < yDiff && y1 < y2) //Going Up
{
if (preview)
{
for (short i = y1; i <= y2; i++)
draw(x1, i, red, green, blue, true);
}
else
{
for (short i = y1; i <= y2; i++)
draw(x1, i, red, green, blue, false);
}
}
}
int main()
{
//Inititialization stuff
for (unsigned int i = 0; i < WIDTHxHEIGHT * 2; i++)
{
XandY[i][0] = i % WIDTH;
XandY[i][1] = i / WIDTH;
}
elementInit(); //Initialize the Elements with their values
currentElement = &metal; //By default, select metal
sf::RenderWindow App(sf::VideoMode(WIDTH, HEIGHT, 32), "ElectroToy");
sf::Thread graphics(&display, &App); //Create the thread that will deal with the graphics
graphics.Launch(); //Launch Graphics thread
sf::Image screen(WIDTH, HEIGHT);
sf::Sprite sprite, prevSprite; //The first one is the main picture, the other is the one for the preview mainPixels
sf::Event Event;
const sf::Input & Input = App.GetInput();
short mouseX = Input.GetMouseX();
short mouseY = Input.GetMouseY();
short oldMouseX = mouseX;
short oldMouseY = mouseY;
bool running = true;
//End of Initialization stuff
while (running) //main loop
{
mouseX = Input.GetMouseX();
mouseY = Input.GetMouseY();
bool leftMouseDown = Input.IsMouseButtonDown(sf::Mouse::Left);
bool rightMouse = Input.IsMouseButtonDown(sf::Mouse::Right);
bool LShift = Input.IsKeyDown(sf::Key::LShift);
while (App.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
{
App.Close();
running = false;
}
}
if (leftMouseDown)
{
oldMouseX = mouseX; //Remember the X,Y co-ordinates when the button was pressed
oldMouseY = mouseY;
while (leftMouseDown)
{
while (App.GetEvent(Event)); //recieve events so it doesn't get stuck in an infinite loop
leftMouseDown = Input.IsMouseButtonDown(sf::Mouse::Left); //update mouse button status
mouseX = Input.GetMouseX();
mouseY = Input.GetMouseY();
lineDraw(oldMouseX, oldMouseY, mouseX, mouseY, true);
for (register unsigned int i = 0; i < WIDTHxHEIGHT * 4; i++) //Combine the two pixel arrays to create what will go on the screen
{
pixels[i] = mainPixels[i];
pixels[i] = previewedPixels[i];
}
wipe();
//previewedPixels = new sf::Uint8[WIDTH * HEIGHT * 4];
screen.LoadFromPixels(WIDTH, HEIGHT, pixels);
sprite.SetImage(screen);
App.Clear();
App.Draw(sprite);
App.Display();
}
lineDraw(oldMouseX, oldMouseY, mouseX, mouseY, false);
}
oldMouseX = mouseX;
oldMouseY = mouseY;
screen.LoadFromPixels(WIDTH, HEIGHT, mainPixels);
sprite.SetImage(screen);
App.Clear();
App.Draw(sprite);
App.Display();
}
}
Well, 好,
for (register unsigned int i = 0; i < WIDTH + HEIGHT * 4; i++)
uses bounds different from 使用不同于
previewedPixels = new sf::Uint8[WIDTH * HEIGHT * 4];
Is that it? 是吗
The register
keyword has been ignored by compilers for decades. register
关键字已被编译器忽略了数十年。 Anyway, I would suggest memset: 无论如何,我建议memset:
memset(previewedPixels, 0, WIDTH * HEIGHT * 4);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.