短篇小说: 试图修改一个在运行时在堆上分配的大型 3D 数组。我相信修改数组的函数(vcross
如下所示)正在创建不会被破坏的内存。
更长的故事:
我有一个大型 3D 双数组(~126000x3x3 或大约 8.6MB),我需要在其上运行一些操作。我不知道这个数组的第一个维度在编译时有多大,所以我使用new
anddelete
操作为堆分配内存。
当我尝试将值存储到此数组时,我得到了分段违规。这让我认为,在将值存储到数组时,我在某处创建内存会浪费,并最终填满堆。
代码编译得很好,但是当我运行它时遇到了段冲突。
static void inpolyh(
double (*f)[3],//pointer to array[3], treated as 2D array where I don't know the first dimension until run-time.
double (*v)[3],
double (*p)[3],
size_t numF,
size_t numP)
{
/*Calculate the baseNormals*/
//allocate memory on the heap
double (*baseNormals)[3] = NULL;//pointer to an array[3]
if ( !(baseNormals = new double[numF][3]) ) { out_of_memory(); }
//store the vector cross products in each array[3] of baseNormals
for (int i=0; i<numF; i++) {
vcross(baseNormals[i],
v[(int)f[i][0]],
v[(int)f[i][1]],
v[(int)f[i][2]]);
//THIS WORKS
}
/*Calculate face normals of tetrahedron*/
//allocate memory on the heap (THIS WORKS)
double (*faceNormals)[3][3] = NULL; //pointer to an array[3] of arrays[3]
if ( !(faceNormals = new double[numP][3][3]) ) { out_of_memory(); }
//store vector cross products into each array[3] of faceNormals
for (int i=0; i<numP; i++ ) {
for (int j=0; j<3; j++ ) {
vcross(faceNormals[i][j],
p[i],
v[ (int) f[i][j] ],
v[ (int) f[i][ (j + 1) % 3 ] ] );
//SEG VIOLATION at i=37560
}
}
delete [] baseNormals;
delete [] faceNormals;
}
这就是我认为罪魁祸首所在的地方。 我认为这个函数会在某个永远不会被破坏的地方创建内存。向量叉积函数接受四个数组 [3] 参数并将一些值分配给第一个输入参数,该参数通过引用传递。
static void vcross(
double (&n)[3],
double a[3],
double b[3],
double c[3])
{
n[0] = b[1] * c[2] - a[1] * c[2] + a[1] * b[2] - b[2]
* c[1] + a[2] * c[1] - a[2] * b[1];
n[1] = b[2] * c[0] - a[2] * c[0] + a[2] * b[0] - b[0]
* c[2] + a[0] * c[2] - a[0] * b[2];
n[2] = b[0] * c[1] - a[0] * c[1] + a[0] * b[1] - b[1]
* c[0] + a[1] * c[0] - a[1] * b[0];
return;
}
其他可能重要的细节:
- 这旨在成为在 matlab 中运行的 mex 函数。
- 默认编码:windows-1252
- MATLAB 根目录:C:\Program Files\MATLAB\R2012b
- MATLAB 版本:8.0.0.783 (R2012b)
- 操作系统:微软视窗7
- 处理器 ID : x86 Family 6 Model 58 Stepping 9, GenuineIntel
- 虚拟机:Java 1.6.0_17-b04 与 Sun Microsystems Inc. Java HotSpot(TM) 64 位服务器 VM 混合模式
- 窗口系统:版本 6.1(内部版本 7601:Service Pack 1)