我们以前有一个.cpp文件(myMexFile.cpp),该文件已编译为MEX文件。我们想将其功能从myMexFile.cpp中移到invraytracer.cpp中,它不是mex文件,而是许多其他文件使用的目标文件。它是一个从raytracer
继承的类。因此,这些向量现在是invraytracer
类的私有成员。
但是,这样做后,我们发现向量(以前是myMexFile.cpp中的全局变量)停止了行为。在它们上使用push_back可能会导致崩溃。 (但并非总是如此)检查它们的.size()和.capacity()会显示大量的,看似随机的值。
以下是在执行其他任何操作之前,genValidAlphasAndBetas中向量大小和容量的示例:
faceToElementMap.size(): 240842449383753
faceToElementMap.capacity() 143891316
validAlphas.size() 18446744073565659644
validAlphas.capacity() 18446744073565659644
validBetas.size() 288471285370204485
validBetas.capacity() 0
我现在无法确认,因为该程序永远无法将其实际打印到调试文件,但在先前的测试中,我看到这些值发生了巨大变化。 (我不确定是在运行之间还是在编译之间)
大致是汇编的样子:
我正在编辑的文件,invraytracer:
g++ -c -I(some include path) -g3 -O0 -m64 -ansi -Wshadow -fPIC -pipe -Wall -fexceptions --param=ssp-buffer-size=4 -mtune=generic -fno-stack-protector invraytracer.cpp -o invraytracer.o
使用invraytracer中的方法的mex文件:
g++ -c -I(some include path) -g3 -O0 -m64 -ansi -Wshadow -fPIC -pipe -Wall -fexceptions --param=ssp-buffer-size=4 -mtune=generic -fno-stack-protector -D__WIN32__ myMexFile.cpp -o myMexFile.o
g++ -m64 -shared -Wl,-Bsymbolic -o myMexFile.mexw64 myMexFile.o invraytracer.o -LC:/Progra~1/MATLAB/R2016b/bin/win64 -LC:/Progra~1/MATLAB/R2016b/extern/lib/win64/mingw64 -lmex -lmx
我尝试将所有标头和代码从子类移至其超类,以防万一我们得到的指针实际上是一个raytracer
对象,而不是{{1 }}就像我们期望的那样。但是,没有喜悦-同样的错误。我得到了链接inverseraytracer
的mexw64文件的对象转储,它们肯定 do 显示了我添加到其中的预期功能。
这就像有一些奇怪的编译器/链接器/对象错误,导致无法正确分配内存。
这是代码的粗略概念。我不能全部提供它,因为它非常大,并且依赖大量外部库来执行它的工作。我已经近似并重命名了一些东西,只显示了一部分代码。
inverseraytracer.h:
inverseraytracer.o
invraytracer.cpp:
class InvRayTracer: public RayTracer
{
// Various private and public functions above this line
// The vectors I moved from the MEX file
std::vector<unsigned int> faceToElementMap;
std::vector<unsigned int> validAlphas;
std::vector<unsigned int> validBetas;
std::vector<SpecialType> validPaths;
// Some of my methods that I added go here...
void foo(args);
void genValidAlphasAndBetas(args);
...
};
从invraytracer调用方法的MEX文件:
void CInvRayTracer::genValidAlphasAndBetas
{
for(unsigned int i = 0; i < triCount; i++)
{
if(some condition)
{
validAlphas.push_back(i);
}
else
{
validBetas.push_back(i);
}
}
}
发现:
此问题仅在 Windows 中发生。当我为了使用Valgrind而在Linux中进行测试时,发现它运行完美!所有值都完全符合我的期望,没有任何错误行为。
VALGRIND在我的代码中也只返回了一个错误,声称单次跳转(在不相关的代码中)是基于未初始化的值,但是我知道这是一个误报。
我确实确实需要在Windows上使用它,所以仍然存在问题。
地址消毒剂注释:
我和void mexFunction(int nlhs,
mxArray *plhs[],
int nrhs,
const mxArray *prhs[]
)
{
// Input argument handling
void* rt = reinterpret_cast<void*>(*muGetPrUInt64(prhs[0]));
InvRayTracer* rayTracer = static_cast<InvRayTracer*>(rt);
rayTracer->genValidAlphasAndBetas(some args);
...
}
一起跑步。您可以在这里找到我的步骤:Can MEX files be run with -fsanitize=address?
最终,它在MATLAB脚本或我的MEX文件中均未发现错误。我想这可以排除这一点。