2012-10-12 49 views
1

我是C#和XNA的新手。剛剛設法編寫了一個生成三角形網格的類。 但有一個問題。我可以得到最多27個節點長度的三角形。 在28它拋出內存異常和在31 -overFlow異常。創建小陣列時出現內存不足和溢出異常

我不明白它是如何溢出或內存不足......試過 計算所有這些內存值,但他們看起來很微小的。

它只是受變量影響的節點數組。節點類不是很大:

float x; 4 B float y; 4 B float z; 4 B int [] con; int [6] 4 * 6 = 24 B 字節傳遞; 1 B Col col;創建三角形所需節點32 B = 4 B

  Total: 41B 

序列總和爲n(n + 1)/ 2

出內存在28

28 * 29/2 = 406的節點

總存儲器:

41 * 406 = 16646 B = 16.26 KB

溢出在31:496個節點是19.9 kB的

我讀過關於「內存不足的例外」的文章,結構尺寸比看起來大,內存不足發生在500MB的大小......我的小三角形不可能達到這樣的程度巨大的尺寸。

這是我的全班同學:

class TriMatrix 
    { 
     int len; 
     int Lenght; 
     Node[] node; 
     VertexPositionColor[] vertex; 

     public class Node 
     { 
      public float x; 
      public float y; 
      public float z; 
      public int[] con; 
      public byte pass; 
      public Color col; 
      public Node(byte passable) 
      { 
       pass = passable; 
       if (pass > 0) 
       { col = Color.Green; } 
       else 
       { col = Color.DarkRed; } 
       x = 0; 
       z = 0; 
       con = new int[6]; 
      } 
     } 

     public TriMatrix(int lenght) 
     { 
      len = lenght; 
      Lenght = 0; 
      byte pass; 
      Random rnd = new Random(); 
      for (int i = 0; i <= len; i++) 
      { 
       Lenght += Lenght + 1; 
      } 
      node = new Node[Lenght]; 
      int num = 0; 
      for (int i = 0; i < len; i++) 
      { 
       for (int j = 0; j <= i; j++) 
       { 

        if (rnd.Next(0, 5) > 0) { pass = 1; } else { pass = 0; } 
        node[num] = new Node(pass); 
        node[num].x = (float)i - (float)j/2.0f; 
        node[num].y = 0; 
        node[num].z = (float)j * 0.6f; 
        if (i < len - 1) { node[num].con[0] = num + i; } else { node[num].con[0] = -1; node[num].col = Color.Violet; } 
        if (i < len - 1) { node[num].con[1] = num + i + 1; } else { node[num].con[1] = -1; } 
        if (j < i) { node[num].con[2] = num + 1; } else { node[num].con[2] = -1; node[num].col = Color.Violet; } 
        if (j < i) { node[num].con[3] = num - i; } else { node[num].con[3] = -1; } 
        if (i > 0) { node[num].con[4] = num - i - 1; } else { node[num].con[4] = -1; } 
        if (i > 0) { node[num].con[5] = num - 1; } else { node[num].con[5] = -1; } 
        if (j == 0) { node[num].col = Color.Violet; } 
        num++; 
       } 
      } 
     } 

     public void Draw(Effect effect, GraphicsDevice graphics) 
     { 
      VertexPositionColor[] verts = new VertexPositionColor[3]; 
      int num = 0; 
      for (int i = 0; i < len-1; i++) 
      { 
       for (int j = 0; j <= i; j++) 
       { 
        foreach (EffectPass pass in effect.CurrentTechnique.Passes) 
        { 
         pass.Apply(); 

         verts[0] = new VertexPositionColor(new Vector3(node[num].x, node[num].y, node[num].z), node[num].col); 
         verts[1] = new VertexPositionColor(new Vector3(node[num + i + 1].x, node[num + i + 1].y, node[num + i + 1].z), node[num + i + 1].col); 
         verts[2] = new VertexPositionColor(new Vector3(node[num + i + 2].x, node[num + i + 2].y, node[num + i + 2].z), node[num + i + 2].col); 
         graphics.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, verts, 0, 1); 

         if (j < i) 
         { 
          verts[0] = new VertexPositionColor(new Vector3(node[num].x, node[num].y, node[num].z), node[num].col); 
          verts[1] = new VertexPositionColor(new Vector3(node[num + i + 2].x, node[num + i + 2].y, node[num + i + 2].z), node[num + i + 2].col); 
          verts[2] = new VertexPositionColor(new Vector3(node[num + 1].x, node[num + 1].y, node[num + 1].z), node[num + 1].col); 
          graphics.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, verts, 0, 1); 
         } 
        } 
        num++; 
       } 
      } 
     } 
    }// endclass 

回答

7

我認爲你的錯誤就在於此循環(以自由來糾正你的拼寫):

for (int i = 0; i <= len; i++) 
{ 
    Length += Length + 1; 
} 

在循環中,你是遞增價值Length本身加1。這實際上意味着您將每次迭代的價值加倍Length,導致指數級增長。

在前幾次迭代中,Length的值爲:1,3,7,15,31,63,...。我們可以概括這個序列,使得在迭代Length的值將是2 i +1 -1。在第28次迭代中,這將是536,870,911。迭代31時,這將是4,294,967,295。

編輯:當你在下面的評論所提到的,用於計算在長度len的三角網格元件的數目正確的修復將是:

for (int i = 1; i <= len; i++) 
{ 
    Length += i; 
} 

這相當於到求和1 + 2 + 3 + … + len,它計算什麼被稱爲triangular number。它可以使用下式計算簡潔:

Length = len * (len + 1)/2; 

,這個數字增長如此之大的原因是,它是一個平方關係;對於長度爲n的一面,您需要面積約爲的一半。

+1

'for(int i = 0; i <= len; i ++){Length + = 1; }'相當於'if(len> 0){Length + = len; }' – Trisped

+0

mmmm ...我不知道是不是這個問題 – Kiaurutis

+0

我需要添加最後一列+1,而不是所有的長度。這一定是錯誤 – Kiaurutis