内存重新分配导致循环分段错误
Memory reallocation causes segmentation fault on loop
我在这里所做的基本上是将一些较小的数组(Bx、By 和 Bz)加入全局数组 (optimisedMesh)。正如您所看到的,Bx、By 和 Bz 的内容和大小是在 b 和 c 循环中设置的。一旦它们被完全定义,它们就会被加入到 optimisedMesh 中。
这个过程应该在每个 "a" for 循环中发生。
我在尝试此操作时发现了两个问题。第一个是当我调用 free(Bx) 时;一旦我不再需要这个数组,调试器 returns 我就出现了分段错误,我不确定为什么。
第二个发生在 "a" for 循环的第二个循环中。在第一个循环
realloc 似乎工作正常,但第二次它 returns 0x0 地址,这会在代码中进一步导致分段错误。
此外,我省略了 By 和 Bz 代码,因为它看起来与 Bx 完全一样。
谢谢你的时间。
int* LBxIA = (int*) calloc (1,sizeof(int*)); int* LBxIB = (int*) calloc (1,sizeof(int*)); int* LByIA = (int*) calloc (1,sizeof(int*)); int* LByIB = (int*) calloc (1,sizeof(int*)); int* LBzIA = (int*) calloc (1,sizeof(int*)); int* LBzIB = (int*) calloc (1,sizeof(int*));
int* LBxFA = (int*) calloc (1,sizeof(int*)); int* LBxFB = (int*) calloc (1,sizeof(int*)); int* LByFA = (int*) calloc (1,sizeof(int*)); int* LByFB = (int*) calloc (1,sizeof(int*)); int* LBzFA = (int*) calloc (1,sizeof(int*)); int* LBzFB = (int*) calloc (1,sizeof(int*));
Quad** Bx = (Quad**) calloc(1,sizeof(Quad*));
int maxSize = Math::maxof(xLenght,yLenght,zLenght);
for(int a = 0; a < maxSize; a++){
int BxCount = 0; int ByCount = 0; int BzCount = 0;
Bx = (Quad**) realloc(Bx,sizeof(Quad*));
for(int b = 0; b < maxSize; b++){
for(int c = 0; c < maxSize; c++){
//Bx
if(a <xLenght && b < yLenght && c < zLenght){
if(cubes[a][b][c] != nullptr){
if(!cubes[a][b][c]->faces[FACE_LEFT].hidden){
if(!LBxIA){
LBxIA = new int(c);
}else{
LBxFA = new int(c);
}
}else{
if(LBxIA && LBxFA){
BxCount++;
Bx = (Quad**) realloc(Bx, BxCount * sizeof(Quad*));
Bx[BxCount - 1] = new Quad(Vector3(a,b,*LBxIA),Vector3(a,b,*LBxFA),Vector3(a,b+1,*LBxIA),Vector3(a,b+1,*LBxFA));
LBxIA = nullptr;
LBxFA = nullptr;
}
}
}else{
if(LBxIA && LBxFA){
BxCount++;
Bx = (Quad**) realloc(Bx, BxCount * sizeof(Quad*));
Bx[BxCount-1] = new Quad(Vector3(a,b,*LBxIA),Vector3(a,b,*LBxFA),Vector3(a,b+1,*LBxIA),Vector3(a,b+1,*LBxFA));
LBxIA = nullptr;
LBxFA = nullptr;
}
if(LBxIB && LBxFB){
BxCount++;
Bx = (Quad**) realloc(Bx, BxCount * sizeof(Quad*));
Bx[BxCount-1] = new Quad(Vector3(a+1,b,*LBxIB),Vector3(a+1,b,*LBxFB),Vector3(a+1,b+1,*LBxIB),Vector3(a+1,b+1,*LBxFB));
LBxIB = nullptr;
LBxFB = nullptr;
}
}
}
}
}
optimisedMeshCount += (BxCount + ByCount + BzCount)*sizeof(Quad*);
optimisedMesh = (Quad**) realloc(optimisedMesh, optimisedMeshCount);
copy(Bx, Bx + BxCount*sizeof(Quad*), optimisedMesh + (optimisedMeshCount - (BxCount + ByCount + BzCount)*sizeof(Quad*)));
copy(By, By + ByCount*sizeof(Quad*), optimisedMesh + (optimisedMeshCount - (BxCount + ByCount + BzCount)*sizeof(Quad*)) + BxCount*sizeof(Quad*));//TODO Aquí error
copy(Bz, Bz + BzCount*sizeof(Quad*), optimisedMesh + (optimisedMeshCount - (BxCount + ByCount + BzCount)*sizeof(Quad*)) + BxCount*sizeof(Quad*) + ByCount*sizeof(Quad*));
free(Bx);
}
我猜,问题出在三行 copy
上。
copy
期望某个容器或内存范围的开始和结束。在你的情况下,你提供 Bx
,这很好,Bx + BxCount*sizeof(Quad*)
,这远远超出了 Bx
内存的末尾。
这是因为Bx + 1
不是Bx
+1个字节,而是&Bx[1]
,也就是第二个元素。同样,Bx + BxCount
将是 copy
预期的 "end"。
这意味着 Bx + BxCount*sizeof(Quad*)
在 64 位系统上超出 Bx
内存范围的八倍。 optimisedMesh
、By
和 Bz
也是如此。结果,您复制了太多元素,结果导致内存损坏。
使用 std::vector
并存储 Quad
而不是指向 Quad
的指针
std::vector<Quad> Bx, By, Bz, optimisedMesh;
for (int a = 0; a < maxSize; a++) {
Bx.clear();
for (int b = 0; b < maxSize; b++) {
for (int c = 0; c < maxSize; c++) {
// ...
Quad qx(Vector3(a,b,*LBxIA),
Vector3(a,b,*LBxFA),
Vector3(a,b+1,*LBxIA),
Vector3(a,b+1,*LBxFA));
Bx.push_back(qx);
// ...
}
}
std::copy(Bx.begin(), Bx.end(), std::back_inserter(optimizedMesh));
std::copy(By.begin(), By.end(), std::back_inserter(optimizedMesh));
std::copy(Bz.begin(), Bz.end(), std::back_inserter(optimizedMesh));
}
如您所见,没有显式分配、重新分配或释放内存,也没有元素计数。
无关,但你也必须注意LBxIA = new int(c);
和LBxIA = nullptr;
,它们会泄漏内存。
我在这里所做的基本上是将一些较小的数组(Bx、By 和 Bz)加入全局数组 (optimisedMesh)。正如您所看到的,Bx、By 和 Bz 的内容和大小是在 b 和 c 循环中设置的。一旦它们被完全定义,它们就会被加入到 optimisedMesh 中。 这个过程应该在每个 "a" for 循环中发生。
我在尝试此操作时发现了两个问题。第一个是当我调用 free(Bx) 时;一旦我不再需要这个数组,调试器 returns 我就出现了分段错误,我不确定为什么。
第二个发生在 "a" for 循环的第二个循环中。在第一个循环 realloc 似乎工作正常,但第二次它 returns 0x0 地址,这会在代码中进一步导致分段错误。
此外,我省略了 By 和 Bz 代码,因为它看起来与 Bx 完全一样。
谢谢你的时间。
int* LBxIA = (int*) calloc (1,sizeof(int*)); int* LBxIB = (int*) calloc (1,sizeof(int*)); int* LByIA = (int*) calloc (1,sizeof(int*)); int* LByIB = (int*) calloc (1,sizeof(int*)); int* LBzIA = (int*) calloc (1,sizeof(int*)); int* LBzIB = (int*) calloc (1,sizeof(int*));
int* LBxFA = (int*) calloc (1,sizeof(int*)); int* LBxFB = (int*) calloc (1,sizeof(int*)); int* LByFA = (int*) calloc (1,sizeof(int*)); int* LByFB = (int*) calloc (1,sizeof(int*)); int* LBzFA = (int*) calloc (1,sizeof(int*)); int* LBzFB = (int*) calloc (1,sizeof(int*));
Quad** Bx = (Quad**) calloc(1,sizeof(Quad*));
int maxSize = Math::maxof(xLenght,yLenght,zLenght);
for(int a = 0; a < maxSize; a++){
int BxCount = 0; int ByCount = 0; int BzCount = 0;
Bx = (Quad**) realloc(Bx,sizeof(Quad*));
for(int b = 0; b < maxSize; b++){
for(int c = 0; c < maxSize; c++){
//Bx
if(a <xLenght && b < yLenght && c < zLenght){
if(cubes[a][b][c] != nullptr){
if(!cubes[a][b][c]->faces[FACE_LEFT].hidden){
if(!LBxIA){
LBxIA = new int(c);
}else{
LBxFA = new int(c);
}
}else{
if(LBxIA && LBxFA){
BxCount++;
Bx = (Quad**) realloc(Bx, BxCount * sizeof(Quad*));
Bx[BxCount - 1] = new Quad(Vector3(a,b,*LBxIA),Vector3(a,b,*LBxFA),Vector3(a,b+1,*LBxIA),Vector3(a,b+1,*LBxFA));
LBxIA = nullptr;
LBxFA = nullptr;
}
}
}else{
if(LBxIA && LBxFA){
BxCount++;
Bx = (Quad**) realloc(Bx, BxCount * sizeof(Quad*));
Bx[BxCount-1] = new Quad(Vector3(a,b,*LBxIA),Vector3(a,b,*LBxFA),Vector3(a,b+1,*LBxIA),Vector3(a,b+1,*LBxFA));
LBxIA = nullptr;
LBxFA = nullptr;
}
if(LBxIB && LBxFB){
BxCount++;
Bx = (Quad**) realloc(Bx, BxCount * sizeof(Quad*));
Bx[BxCount-1] = new Quad(Vector3(a+1,b,*LBxIB),Vector3(a+1,b,*LBxFB),Vector3(a+1,b+1,*LBxIB),Vector3(a+1,b+1,*LBxFB));
LBxIB = nullptr;
LBxFB = nullptr;
}
}
}
}
}
optimisedMeshCount += (BxCount + ByCount + BzCount)*sizeof(Quad*);
optimisedMesh = (Quad**) realloc(optimisedMesh, optimisedMeshCount);
copy(Bx, Bx + BxCount*sizeof(Quad*), optimisedMesh + (optimisedMeshCount - (BxCount + ByCount + BzCount)*sizeof(Quad*)));
copy(By, By + ByCount*sizeof(Quad*), optimisedMesh + (optimisedMeshCount - (BxCount + ByCount + BzCount)*sizeof(Quad*)) + BxCount*sizeof(Quad*));//TODO Aquí error
copy(Bz, Bz + BzCount*sizeof(Quad*), optimisedMesh + (optimisedMeshCount - (BxCount + ByCount + BzCount)*sizeof(Quad*)) + BxCount*sizeof(Quad*) + ByCount*sizeof(Quad*));
free(Bx);
}
我猜,问题出在三行 copy
上。
copy
期望某个容器或内存范围的开始和结束。在你的情况下,你提供 Bx
,这很好,Bx + BxCount*sizeof(Quad*)
,这远远超出了 Bx
内存的末尾。
这是因为Bx + 1
不是Bx
+1个字节,而是&Bx[1]
,也就是第二个元素。同样,Bx + BxCount
将是 copy
预期的 "end"。
这意味着 Bx + BxCount*sizeof(Quad*)
在 64 位系统上超出 Bx
内存范围的八倍。 optimisedMesh
、By
和 Bz
也是如此。结果,您复制了太多元素,结果导致内存损坏。
使用 std::vector
并存储 Quad
而不是指向 Quad
std::vector<Quad> Bx, By, Bz, optimisedMesh;
for (int a = 0; a < maxSize; a++) {
Bx.clear();
for (int b = 0; b < maxSize; b++) {
for (int c = 0; c < maxSize; c++) {
// ...
Quad qx(Vector3(a,b,*LBxIA),
Vector3(a,b,*LBxFA),
Vector3(a,b+1,*LBxIA),
Vector3(a,b+1,*LBxFA));
Bx.push_back(qx);
// ...
}
}
std::copy(Bx.begin(), Bx.end(), std::back_inserter(optimizedMesh));
std::copy(By.begin(), By.end(), std::back_inserter(optimizedMesh));
std::copy(Bz.begin(), Bz.end(), std::back_inserter(optimizedMesh));
}
如您所见,没有显式分配、重新分配或释放内存,也没有元素计数。
无关,但你也必须注意LBxIA = new int(c);
和LBxIA = nullptr;
,它们会泄漏内存。