我在为mingw32编译一些代码时遇到问题,链接一个mingw32编译的库。当我调用我动态链接到的库中的类的成员函数(即构造函数)时,参数会以错误的顺序被压入堆栈。
以下是一个例子:
Program received signal SIGSEGV, Segmentation fault.
0x65e717e9 in TCODMap::TCODMap (this=0x40, width=48, height=40)
at src/fov.cpp:28
28 src/fov.cpp: No such file or directory.
(gdb) backtrace
#0 0x65e717e9 in TCODMap::TCODMap (this=0x40, width=48, height=40)
at src/fov.cpp:28
#1 0x00401bda in map::map (this=0x8683c8, dim=..., fill=0 '\000')
at src/map.cpp:12
#2 0x004017d7 in next_init () at src/main.cpp:24
#3 0x00401b8e in main (argc=1, argv=0x862fc8) at src/main.cpp:98
我对TCODMap构造函数的调用具有参数width=64
和height=48
,但值得注意的是this
隐式参数设置为64(0x40),width
已设置到48,并且height
被设置为一些垃圾值40.在这种情况下,构造函数被调用为我的用户代码中的另一个类的初始化程序的一部分。
有问题的代码:
map::map(loc dim, uint8 fill) : _dim(dim), tcodmap(_dim.x, _dim.y), actors()
{
_size = _dim.x * _dim.y;
_data = new uint8[_size];
for (int xi = 0; xi < _dim.x; xi++)
{
for (int yi = 0; yi < _dim.y; yi++)
{
put(xi, yi, fill);
}
}
}
似乎是thiscall
调用约定,它说this
指针应该最后被推到堆栈上,这样它在词法列表中是词法上的第一个,没有被正确地遵守。
我该如何解决这个问题?
答案 0 :(得分:0)
我写了一个测试程序来检查你想要做什么。首先,您在运行时获取错误,而不是在编译时,因为您提供了gdb的堆栈跟踪。
#include <iostream>
struct Data{
int _x;
int _y;
};
class A{
public:
A(){}
A(int x){}
A(const A&,int y){}
A(int x , int y)
{
}
};
class B{
Data _d;
A _a;
public:
B(Data d,int fill):_d(d),_a(_d._x,_d._y)
{
}
};
int main()
{
Data d;
d._x=1;
d._y=2;
B instance(d,4);
return 0;
}
堆栈跟踪:
> Breakpoint 1, B::B (this=0x7fffffffe1a0, d=..., fill=4) at this.cpp:26
> 26 B(Data d,int fill):_d(d),_a(_d._x,_d._y) (gdb) s A::A
> (this=0x7fffffffe1a8, x=1, y=2) at this.cpp:17 17 } (gdb) bt
> #0 A::A (this=0x7fffffffe1a8, x=1, y=2) at this.cpp:17
> #1 0x00000000004006fb in B::B (this=0x7fffffffe1a0, d=..., fill=4)
> at this.cpp:26
> #2 0x0000000000400652 in main () at this.cpp:39
这里指出'this'隐式指针指向一个有效的地址,除非你的程序导致“堆栈缓冲区溢出”,这会破坏分配给tcodmap的'this'指针的内存。
您应该分享完整代码的更多详细信息,以及如何使用此程序。 您是在每次运行中遇到此问题还是随机的?