c++ - 结构中的结构,动态内存分配

标签 c++ struct malloc

我正在制作一个 3D 应用程序,其中一艘船必须驶过浮标轨道。我还需要将轨道存储在组或“布局”中。浮标类基本上是一个“浮标布局”列表,其中是一个“浮标轨道”列表,其中是一个浮标列表。

我检查了局部变量观察器,构造函数中的所有内存分配似乎都有效。稍后调用 calculateCoordinates 函数时,它会进入 for 循环。在 for 循环的第一次迭代中,函数指针被使用并且工作正常,但随后在这一行上

ctMain[j+1][1] = 0;

函数指针设置为 NULL。我猜它与未正确分配或寻址的结构有关。我不确定从这里做什么。也许我不明白 malloc 是如何工作的。

更新 我用双 ** main_track 替换了 M3DVector3d main_track,认为 malloc 可能没有正确处理 typedef。但是稍后在 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,它是你的 friend 。但无论如何...

首先,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));
}

关于c++ - 结构中的结构,动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15869532/

相关文章:

c++ - 是否允许实现将公共(public)成员添加到标准类型?

c++ - 具有指向其父对象的指针的对象是否应该定义复制构造函数?

c++ - 如何获取卷 GUID

c - while循环内存泄漏

c - 如何在 C 中创建动态字符串数组?

c++ - Cygwin:打开句柄时删除文件

c - 在C编程中,有没有办法在子结构体(结构体中的结构体)中获取函数的返回值?

c - 动态分配多个结构的数组

C - 结构数组元素交换

C malloc(段错误 : 11)