2012-10-12 23 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