简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM