You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++问题:Float数组在大索引位置后无法存储有效值

问题分析与解决方案

看起来你遇到的是数组越界导致内存覆盖的典型C/C++隐蔽bug,这也是你看到法线后半段全为0的核心原因。

核心问题:flagVertices数组容量不足,越界写入覆盖normals

先算清楚内存需求:

  • 你的双层循环每轮(i,j)会生成2个三角形,每个三角形含3个顶点,每个顶点存x/y/z三个分量——所以每轮循环要占用 3*3*2 = 18 个float位置。
  • 但你定义的flagVertices大小是 N*N*VALS_PER_VERT*VERTICES_PER_QUAD,如果VALS_PER_VERT=3(对应顶点的3个分量)、VERTICES_PER_QUAD=4(四边形的4个顶点),总容量只有 N*N*3*4=12N²,远小于实际需要的 18N²。

当flagVertices被写满后,后续的顶点数据会溢出到栈上相邻的内存区域——也就是你的normals数组。这就导致刚计算好存入normals的法线,立刻被越界写入的顶点数据覆盖成0(或其他顶点值),读取时自然只能看到无效的0值。

修复步骤

  1. 修正数组大小匹配实际需求
    因为你每个四边形用了6个重复顶点(而非优化后的4个),所以VERTICES_PER_QUAD应该设为6,修改数组定义:

    // 每个四边形6个顶点,每个顶点3个分量,大小刚好匹配实际需求
    float flagVertices[ N*N*VALS_PER_VERT*6 ]; 
    // 法线数组大小同步调整,你的代码每轮存2组法线(每组3分量),总容量完全足够
    float normals[ N*N*VALS_PER_VERT*6 ]; 
    

    或者直接用准确的计算式定义:N*N*2*3*3(N*N个四边形 × 每个2三角形 × 每个3顶点 × 每个3分量)。

  2. 可选优化:复用顶点减少内存浪费
    你当前代码重复存储了大量顶点(比如(1,1)和(0,0)在两个三角形中都存了两次),可以改用顶点索引缓冲(EBO)复用顶点,这样flagVertices的大小可以缩减为(N+1)*(N+1)*3(只存储所有唯一的网格顶点),同时法线也可以对应每个顶点计算,既节省内存又更符合图形学的常规做法。

快速验证方法

你可以在循环中加入简单的越界检查,比如每次idxFlag自增后,打印它的值和数组总容量,当idxFlag超过数组长度时触发提示,就能直观确认是否是越界问题。

内容的提问来源于stack exchange,提问作者HypoFreak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:41:59