将数组的所有点设置为0,对重新分配动态内存有不同的影响

时间:2012-03-04 04:46:07

标签: c++ arrays

我正在尝试制作一个能够在像素网格上绘制线条然后再到位图的东西。我可以(几乎)通过使用'new'重新分配内存来获得我想要的效果(尽管数组要大到删除[]所以我最终会出现内存泄漏)。

我的问题是,我不能为了我的生活,弄清楚为什么要这样做:

for (register unsigned int i = 0; i < WIDTH + HEIGHT * 4; i++)
{
    previewedPixels[i] = 0;
}

与做

的效果不同
previewedPixels = new sf::Uint8[WIDTH * HEIGHT * 4];

这是代码的其余部分,将其放在透视图中(注释重新分配内存并导致内存泄漏的行)。请原谅这个烂摊子: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();
    }
}

2 个答案:

答案 0 :(得分:3)

那么,

for (register unsigned int i = 0; i < WIDTH + HEIGHT * 4; i++)

使用与

不同的边界
previewedPixels = new sf::Uint8[WIDTH * HEIGHT * 4];
是吗?

答案 1 :(得分:0)

编译器几十年来忽略了register关键字。无论如何,我建议memset:

memset(previewedPixels, 0, WIDTH * HEIGHT * 4);