2014-04-11 97 views
-2

我正在做一個基於圖層的遊戲(以產生視差效果),我需要從每個圖層裁剪一個圖像來組成一個場景。但是,記憶中有些東西在積累,我不知道是什麼。我用delete[]填充我的代碼是絕望的措施。爲什麼我的程序消耗了一堆內存?

ImageClass.h

#include <math.h> 

class Image { 
public: 
    Image(int w, int h){ 
    width = w; height = h; 
    pixels = new int[w*h*3]; 
    } 

    Image(){} 

    void setPixel(int a, int r, int g, int b, int x, int y){ 
     pixels[x + y * width] = (a << 24) | (r << 16) | (g << 8) | b; 
    } 

    int getPixel(int x, int y){ 
    return pixels[x+y*width]; 
    } 
    int getWidth(){ return width; } 

    int getHeight(){ return height; } 

    int* getPixels() { 
     return pixels; 
    } 

    void composition(int xi, int yi, int *foreground, int fw, int fh) { 
     for (int i = yi; (i < fh) && (i < height); i++) { 
      for (int j = xi; (j < fw) && (j < width); j++) { 
       int aF = (foreground[j + i * fw] >> 24) & 0xff; 
       int rF = (foreground[j + i * fw] >> 16) & 0xff; 
       int gF = (foreground[j + i * fw] >> 8) & 0xff; 
       int bF = (foreground[j + i * fw]) & 0xff; 

       int rI = (pixels[j + i * width] >> 16) & 0xff; 
       int gI = (pixels[j + i * width] >> 8) & 0xff; 
       int bI = (pixels[j + i * width]) & 0xff; 

       float am = aF/(float)255; 

       int c1 = (rF * am) + rI * (1 - am); 
       int c2 = (gF * am) + gI * (1 - am); 
       int c3 = (bF * am) + bI * (1 - am); 

       pixels[j + i * width] = (aF << 24) | (c1 << 16) | (c2 << 8) | c3; 
      } 
     } 
     delete[] foreground; 
    } 

private: 
    int *pixels; 
     int width, height; 
}; 

Layer.h

#include <fstream> 
#include "ImageClass.h" 

using namespace std; 

class Layer { 
    private: 
     Image *img; 
     float scrollY; 
     float scrollX; 
     float ypos; 
     float xpos; 

    public: 
     Layer(){ 
      img = NULL; 
      scrollX = 0; 
      scrollY = 0; 
      ypos = 0; 
      xpos = 0; 
     } 

     Layer(Image *pImg, float sy, float sx, float yp, float xp) { 
      img = pImg; 
      scrollX = sx; 
      scrollY = sy; 
      ypos = yp; 
      xpos = xp; 
     } 

     Layer(char* path, float sy, float sx, float yp, float xp) { 
      ifstream arg(path); 
      if (!arg.is_open()) { 
       exit(EXIT_FAILURE); 
      } 

      char word[10]; 

      //Reading type 
      arg >> word; 

      //Reading width 
      int argWidth; 
      arg >> word; 
      argWidth = atoi(word); 

      //Reading height 
      int argHeight; 
      arg >> word; 
      argHeight = atoi(word); 

      //Reading max 
      arg >> word; 

      //Creating an image with arg size 
      img = new Image(argWidth, argHeight); 

      int a, r, g, b; 
      for (int i = 0; i < argHeight; i++) { 
       for (int j = 0; j < argWidth; j++) { 
        arg >> word; 
        a = atoi(word); 
        arg >> word; 
        r = atoi(word); 
        arg >> word; 
        g = atoi(word); 
        arg >> word; 
        b = atoi(word); 
        img->setPixel(a, r, g, b, j, i); 
       } 
      } 

      arg.close(); 
      //End of reading 

      scrollX = sx; 
      scrollY = sy; 
      ypos = yp; 
      xpos = xp; 
     } 

     int* subImage(int wp, int hp) { 
      int* subPixels = new int[wp * hp]; 
      for (int i = 0; (i < hp) && (i < img->getHeight()); i++) { 
       for (int j = 0; (j < wp) && (j < img->getWidth()); j++) { 
        subPixels[j + i * wp] = img->getPixel(j + xpos, i + ypos); 
       } 
      } 
      return subPixels; 
      delete[] subPixels; 
     } 

     void horizontalScrolling(bool direction){ 
      //if direction equals true, it goes to the right. Else, left 
      if (direction) { 
       xpos += scrollX; 
      } else { 
       xpos -= scrollX; 
      } 
     } 

     void verticalScrolling(bool direction){ 
      //if direction equals true, it goes up. Else, down 
      if (direction) { 
       ypos -= scrollY; 
      } else { 
       ypos += scrollY; 
      } 
     } 

     float getScrollX() { 
      return scrollX; 
     } 

     float getScrollY() { 
      return scrollY; 
     } 

     float getPosX() { 
      return xpos; 
     } 

     float getPosY() { 
      return ypos; 
     } 

     void setPosX(float xp){ 
      xpos = xp; 
     } 

     void setPosY(float yp){ 
      ypos = yp; 
     } 

     Image* getImage() { 
      return img; 
     } 

}; 

#include "Layer.h" 
#include <math.h> 

class Scene { 
    private: 
     int width; 
     int height; 
     Layer *layers[10]; 
     Image *finalScene; 

    public: 
     Scene(int w, int h) { 
      width = w; 
      height = h; 
      finalScene = new Image(w, h); 
      loadLayers(); 
     } 

     void loadLayers() { 
      //loading layer 0 
      layers[0] = new Layer("Background", 1, 1.5, 0, 0); 
      layers[1] = new Layer("Island", 5, 5, 0, 0); 
     } 

     void mountScene() { 
      delete[] finalScene; 
      finalScene = new Image(width, height); 
      finalScene->composition(0, 0, layers[0]->subImage(width, height), width, height); 
      finalScene->composition(0, 0, layers[1]->subImage(width, height), width, height); 
     } 

     void sceneHScrolling(bool direction) { 
      int cont = 0; 
      int layersCreated = 2; 
      while (cont < layersCreated) { 
       int delta = layers[cont]->getImage()->getWidth() - width; 
       int posX = layers[cont]->getPosX(); 
       if (direction) { 
        if (posX < (delta)) { 
         layers[cont]->horizontalScrolling(direction); 
        } 
       } else { 
        if (posX 
> 0) { 
         layers[cont]->horizontalScrolling(direction); 
        } 
       } 
       cont++; 
      } 
     } 

     void sceneVScrolling(bool direction) { 
      int cont = 0; 
      int layersCreated = 2; 
      while (cont < layersCreated) { 
       int delta = layers[cont]->getImage()->getHeight() - height; 
       int posY = layers[cont]->getPosY(); 
       if (direction) { 
        if (posY > 0) { 
         layers[cont]->verticalScrolling(direction); 
        } 
       } else { 
        if (posY < delta) { 
         layers[cont]->verticalScrolling(direction); 
        } 
       } 
       cont++; 
      } 
     } 

     int* getScene() { 
      return finalScene->getPixels(); 
     } 

     Layer* getLayer(int i){ 
      return layers[i]; 
     } 
}; 
+1

TL; DR ....但一般情況下你可能想嘗試內存調試工具。起點是[valgrind](http://valgrind.org/) – jsantander

+2

只有兩個提示:a)使用valgrind。 b)對未來而言:刪除不僅是好事,而且絕對是詭祕的。缺少=錯誤。加上絕望的措施可能會失敗,因爲你錯過了一些應該在的地方。 – deviantfan

+0

....或者將它添加到不應該出現的地方:D – jsantander

回答

3

我用delete []填充我的代碼是絕望的措施。

你需要比這更有紀律。 每個new[]需要與delete[]和每個newdelete平衡。因此,添加delete來電不僅僅是一個絕望的措施:這是至關重要的。

否則你會泄漏記憶,這是發生在這裏。

或者,爲什麼不使用std::vector<int>取而代之?這樣,所有的內存都爲您管理。

+0

是的,但是OP在他們不屬於的地方用'deletes'丟棄了代碼。 – datenwolf

相關問題