+-
c++函数,由不同的地方调用出来的结果不同,为什么?

程序的主要目标是画N条线段。
创建一个数组来收纳N条线段,
N是可变的,button每点击一次就扩容一次,
扩容后把随机生成的线段放到数组里面,
定时器不断地驱动着另一个函数来访问这个数组,
依据数组里面的数据,在OPENGL里画出直线。

//1个点由X,Y,Z(空间点)来描述。
struct Point3D {
    unsigned int x, y, z;
    Point3D(unsigned int _x, unsigned int _y, unsigned int _z) : x(_x), y(_y), z(_z) {}
};

//1条线段由2个端点来描述,
struct Line3D
{
    Point3D start,end;
    Line3D(Point3D _s, Point3D _e) :start(_s), end(_e) {};
};

unsigned int Line3D_Num = 0;//记录线段总数
unsigned int pos = -1;//扩容时用到
Line3D ** pLine3DArr ;//收纳线段的数组

下面是画线函数,

//画1条线段,输入参数是线段的两个点。
void DrawLine(Point3D start,Point3D  end)
{
    //之所以定义XYZABC,出于好辩认的目的
    GLfloat x, y, z;
    GLfloat a, b, c;
    x = (GLfloat)start.x / 225;
    y = (GLfloat)start.y / 225;
    z = (GLfloat)start.z / 225;
    a = (GLfloat)end.x / 225;
    b = (GLfloat)end.y / 225;
    c = (GLfloat)end.z / 225;
    debug(("DrawLine >>\n"));
    debug((" [%d,%d,%d],[%d,%d,%d]\n", start.x, start.y, start.z, end.x, end.y, end.z));
    debug((" [%.3f,%.3f,%.3f],[%.3f,%.3f,%.3f]\n", x, y, z, a, b, c));

    glBegin(GL_LINES);
    {
        glColor3ub(255, 0, 0);
        glVertex3f(x, y, z); glVertex3f(a, b, c);
    }
    glEnd();
}

下面程序是把数组里面线段全画出来


void DrawLine3D(Line3D ** arr)
{
    for (unsigned int i = 0; i < Line3D_Num; i++)
    {
        debug(("i:%d\n", i));

        Line3D * ptr = arr[i];
        Point3D p1 = ptr->start;
        Point3D p2 = ptr->end;

        DrawLine(p1, p2);
    }
    
}

下面程序由button点击时触发

bool debug = 1;

            Line3D_Num ++;
            //数组扩容
            Line3D ** pnew = (Line3D **)realloc(pLine3DArr, sizeof(Line3D *)*Line3D_Num);
            if (!pnew)
            {
                debug(("485 >> realloc error\n"));
                break;
            }
            pLine3DArr = pnew;
            
            //增量扩容,
            pos++;
            for (int i = pos; i < Line3D_Num; i++)
            {
                Point3D p1(rnd(30, 255), rnd(30, 255), 30);
                Point3D p2(rnd(30, 255), rnd(30, 255), 30);
                Line3D L1(p1, p2);
                pLine3DArr[i] = (Line3D *)malloc(sizeof(Line3D *));
                pLine3DArr[i] = &L1;

            }

            if (debug)
            {
                debug(("Line3D_Num:%d\n", Line3D_Num));
                DrawLine3D(pLine3DArr);
                debug(("________________________\n"));
            }

还有个随机数函数,随机数函数是有效的,四个随机都不相同

unsigned int rnd(unsigned int a, unsigned int b)
{
    LARGE_INTEGER seed;
    QueryPerformanceFrequency(&seed);
    QueryPerformanceCounter(&seed);
    srand(seed.QuadPart);//初始化一个以微秒为单位的时间种子
    unsigned int number = rand() % (b - a + 1) + a;
    debug(("rnd>>%d\n", number));
    return number;
}

最后是调用画线的函数

//渲染一帧
void DrawGLScene(GLfloat rotx, GLfloat roty, GLfloat rotz)
{
    //glViewport(0, 0, 2 * LOWORD(lParam), 2 * HIWORD(lParam));

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        // 清除旧画面及景深缓存
    glLoadIdentity();                                        // 重置模型观察矩阵
    glTranslatef(0.0f,0.0f,rotz);                            // 顺着Z轴偏移rotz
    glRotatef(roty,1.0f,0.0f,0.0f);                        // 绕X轴旋转roty
    glRotatef(rotx,0.0f,1.0f,0.0f);                        // 绕Y轴旋转rotx

    //画正方体
    glBegin(GL_QUADS);
    {
        glColor3ub(255,0,0);glVertex3f(-0.051f,+0.051f,-0.051f);glVertex3f(+0.051f,+0.051f,-0.051f);glVertex3f(+0.051f,-0.051f,-0.051f);glVertex3f(-0.051f,-0.051f,-0.051f);
        glColor3ub(0,255,0);glVertex3f(-0.051f,+0.051f,+0.051f);glVertex3f(-0.051f,-0.051f,+0.051f);glVertex3f(+0.051f,-0.051f,+0.051f);glVertex3f(+0.051f,+0.051f,+0.051f);
        glColor3ub(0,0,255);glVertex3f(+0.051f,+0.051f,+0.051f);glVertex3f(+0.051f,-0.051f,+0.051f);glVertex3f(+0.051f,-0.051f,-0.051f);glVertex3f(+0.051f,+0.051f,-0.051f);
        glColor3ub(255,255,0);glVertex3f(-0.051f,+0.051f,+0.051f);glVertex3f(-0.051f,+0.051f,-0.051f);glVertex3f(-0.051f,-0.051f,-0.051f);glVertex3f(-0.051f,-0.051f,+0.051f);
        glColor3ub(255,0,255);glVertex3f(-0.051f,+0.051f,+0.051f);glVertex3f(+0.051f,+0.051f,+0.051f);glVertex3f(+0.051f,+0.051f,-0.051f);glVertex3f(-0.051f,+0.051f,-0.051f);
        glColor3ub(0,255,255);glVertex3f(-0.051f,-0.051f,+0.051f);glVertex3f(-0.051f,-0.051f,-0.051f);glVertex3f(+0.051f,-0.051f,-0.051f);glVertex3f(+0.051f,-0.051f,+0.051f);
    }
    glEnd();

    //画坐标轴
    glLineWidth (1.0);
    glBegin(GL_LINES);
    {
        //X
        glColor3ub(255, 0, 0);
        glVertex3f(-1,0,0);glVertex3f(1,0,0);
        glVertex3f(1,0,0);glVertex3f(1-0.05f,0.05f,0);
        glVertex3f(1,0,0);glVertex3f(1-0.05f,-0.05f,0);
        glVertex3f(1,0,0);glVertex3f(1-0.05f,0,0.05f);
        glVertex3f(1,0,0);glVertex3f(1-0.05f,0,-0.05f);
        //Y
        glColor3ub(0, 255, 0);
        glVertex3f(0,-1,0);glVertex3f(0,1,0);
        glVertex3f(0,1,0);glVertex3f(0.05f,1-0.05f,0);
        glVertex3f(0,1,0);glVertex3f(-0.05f,1-0.05f,0);
        glVertex3f(0,1,0);glVertex3f(0,1-0.05f,0.05f);
        glVertex3f(0,1,0);glVertex3f(0,1-0.05f,-0.05f);
        //Z
        glColor3ub(0, 0, 255);
        glVertex3f(0,0,-1);glVertex3f(0,0,1);
        glVertex3f(0,0,1);glVertex3f(0.05f,0,1-0.05f);
        glVertex3f(0,0,1);glVertex3f(-0.05f,0,1-0.05f);
        glVertex3f(0,0,1);glVertex3f(0,0.05f,1-0.05f);
        glVertex3f(0,0,1);glVertex3f(0,-0.05f,1-0.05f);
    }
    glEnd();

        //红线
    display(px1, py1, px2, py2);
    
    //出问题的地方
    DrawLine3D(pLine3DArr);

    glFlush();
    SwapBuffers(hDC);
};

出问题的地方是

DrawLine3D(pLine3DArr);
//把这个函数放在扩容的时候,出来的数据是正常的,完全符合期待(短红框)
//但,如果把这个函数放到DrawGLScene(),出来的数据完全乱了,(长红框)
//数组是公共变量,同一个函数,同一个数组,出来的结果完全不同。


你的代码有一个比较初级的错误

...
Line3D L1(p1, p2);
pLine3DArr[i] = (Line3D *)malloc(sizeof(Line3D *));
pLine3DArr[i] = &L1;

L1 是在循环体内的一个局部变量,然后你malloc了一个指针的空间(4/8个字节),然后让这个指针指向了 L1,但循环结束后,L1就被释放了,你记录的L1指针就成了野指针。
正确的代码应该是:

...
Line3D L1(p1, p2);
pLine3DArr[i] = (Line3D *)malloc(sizeof(Line3D));
memcpy(pLine3DArr[i], &L1, sizeof(Line3D));