我正在制作一个3D应用程序,其中船必须通过浮标轨道行驶。我还需要在组或"布局"中存储轨道。浮标类基本上是一个"浮标布局"列表,其中是一个"浮标轨迹"列表,其中是一个浮标列表。
我检查了局部变量监视器,构造函数中的所有内存分配似乎都有效。稍后,当调用calculateCoordinates函数时,它将进入for循环。在for循环的第一次迭代中,使用了函数的指针,并且工作正常,但是在
这一行ctMain[j+1][1] = 0;
函数指针被设置为NULL。我猜它与结构体没有被正确分配或处理有关。我不知道从这里该怎么办。也许我不理解malloc是如何工作的。
我用双** main_track替换了M3DVector3d main_track,认为也许malloc没有正确处理类型定义。但是,当我试图在calculateCoordinates中稍后访问main_track变量时,我得到了同样的错误。
它最终是由于访问
行的指针错误而导致的内存损坏。rotatePointD(&(cTrack->main_track[j]), rotation);
当我试图访问它时,它只会导致一个错误。
// Buoys.h
////////////////////////////////////////////
struct buoy_layout_t;
struct buoy_track_t;
typedef double M3DVector3d[3];
class Buoys {
public:
Buoys();
struct buoy_layout_t ** buoyLayouts;
int nTrackLayouts;
int currentLayoutID;
void calculateCoordinates();
};
struct buoy_track_t {
int nMain, nYellow, nDistract;
M3DVector3d * main_track,
yellow_buoys,
distraction_buoys;
double (*f)(double x);
double (*fp)(double x);
double thickness;
M3DVector3d start, end;
};
struct buoy_layout_t {
int nTracks;
buoy_track_t ** tracks;
};
// Buoys.cpp
/////////////////////////////
// polynomial and its derivative, for shape of track
double buoyfun1(double x) {return (1.0/292.0)*x*(x-12.0)*(x-24.0);}
double buoyfun1d(double x) {return (1.0/292.0)*((3.0*pow(x,2))-(72.0*x)+288.0);}
// ... rest of buoy shape functions go here ...
Buoys::Buoys() {
struct buoy_layout_t * cLayout;
struct buoy_track_t * cTrack;
nTrackLayouts = 1;
buoyLayouts = (buoy_layout_t **) malloc(nTrackLayouts*sizeof(*buoyLayouts));
for (int i = 0; i < nTrackLayouts; i++) {
buoyLayouts[i] = (buoy_layout_t *) malloc(sizeof(*(buoyLayouts[0])));
}
currentLayoutID = 0;
// ** Layout 1 **
cLayout = buoyLayouts[0];
cLayout->nTracks = 1;
cLayout->tracks = (buoy_track_t **) malloc(sizeof(*(cLayout->tracks)));
for (int i = 0; i < 1; i++) {
cLayout->tracks[i] = (buoy_track_t *) malloc (sizeof(*(cLayout->tracks)));
}
cTrack = cLayout->tracks[0];
cTrack->main_track = (M3DVector3d *) malloc(30*sizeof(*(cTrack->main_track)));
cTrack->nMain = 30;
cTrack->f = buoyfun1;
cTrack->fp = buoyfun1d;
cTrack->thickness = 5.5;
cTrack->start[0] = 0; cTrack->start[1] = 0; cTrack->start[2] = 0;
cTrack->end[0] = 30; cTrack->end[1] = 0; cTrack->end[2] = -19;
// ... initialize rest of layouts here ...
// ** Layout 2 **
// ** Layout 3 **
// ...
// ** Layout N **
calculateCoordinates();
}
void Buoys::calculateCoordinates()
{
int i, j;
buoy_layout_t * cLayout = buoyLayouts[0];
for (i = 0; i < (cLayout->nTracks); i++) {
buoy_track_t * cTrack = cLayout->tracks[i];
M3DVector3d * ctMain = cTrack->main_track;
double thickness = cTrack->thickness;
double rotation = getAngleD(cTrack->start[0], cTrack->start[2],
cTrack->end[0], cTrack->end[2]);
double full_disp = sqrt(pow((cTrack->end[0] - cTrack->start[0]), 2)
+ pow((cTrack->end[2] - cTrack->start[2]), 2));
// nBuoys is nBuoys per side. So one side has nBuoys/2 buoys.
for (j=0; j < cTrack->nMain; j+=2) {
double id = j*((full_disp)/(cTrack->nMain));
double y = (*(cTrack->f))(id);
double yp = (*(cTrack->fp))(id);
double normal, normal_a;
if (yp!=0) {
normal = -1.0/yp;
}
else {
normal = 999999999;
}
if (normal > 0) {
normal_a = atan(normal);
}
else {
normal_a = atan(normal) + PI;
}
ctMain[j][0] = id + ((thickness/2.0)*cos(normal_a));
ctMain[j][1] = 0;
ctMain[j][2] = y + ((thickness/2.0)*sin(normal_a));
ctMain[j+1][0] = id + ((thickness/2.0)*cos(normal_a+PI));
ctMain[j+1][1] = 0; // function pointers get set to null here
ctMain[j+1][2] = y + ((thickness/2.0)*sin(normal_a+PI));
}
for (j=0; j < cTrack->nMain; j++) {
rotatePointD(&(cTrack->main_track[j]), rotation);
}
}
}
除非有学习指针的要求,或者你不能使用STL,鉴于你正在使用c++,我强烈建议你使用更多的STL,它是你的朋友。但无论如何…
首先,ctMain的类型是*M3DVector3D。所以你可以安全地访问ctMain[0],但你不能访问ctMain[1],也许你的意思是ctMain的类型是**M3DVector3D,在这种情况下,你写的初始化行是:
cTrack->main_track = (M3DVector3d *) malloc(30*sizeof(*(cTrack->main_track)));
有意义
更多的音符你为什么在这里分配30个?
cTrack->main_track = (M3DVector3d *) malloc(30*sizeof(*(cTrack->main_track)));
给定main_track的类型,您只需要:
cTrack->main_track = (M3DVector3d *) malloc(sizeof(M3DVector3d));
此外,出于组织目的,在执行sizeof时,您可能希望提供实际类型来检查sizeof,而不是变量(应该没有区别,只是组织),这两个更改:
buoyLayouts = (buoy_layout_t **) malloc(nTrackLayouts*sizeof(buoy_layout_t*));
for (int i = 0; i < nTrackLayouts; i++) {
buoyLayouts[i] = (buoy_layout_t *) malloc(sizeof(buoy_layout_t));
}
cLayout->tracks = (buoy_track_t **) malloc(clayout->nTracks * sizeof(buoy_track_t*));
for (int i = 0; i < 1; i++) {
cLayout->tracks[i] = (buoy_track_t *) malloc(sizeof(buoy_track_t));
}