重复引用时,struct值会发生变化

时间:2011-11-01 19:39:24

标签: c

我正在尝试在C中编写一个胶体模拟程序,我遇到了一个奇怪的问题,我不知道如何解决 - 我已经将代码减少到显示相同类型错误的最小值。 (我很抱歉,代码的长度......)

/** main.c **/
#include <stdio.h>

/** typedefs **/
typedef struct { double x, y, z; } point;
typedef struct {
    double radius;
    point pos, potential, velocity;
} particle;
typedef struct {
    int num;                // size of particle array
    particle *particles;
} trough;
typedef struct { trough trough; } experiment;

void printPoint(point a) { printf("%f, %f, %f\n", a.x, a.y, a.z); }

/** initializations **/
point initPoint(double x, double y, double z) {
    point new_point = { .x = x, .y = y, .z = z };
    return(new_point);
}
particle initParticle(double radius, point pos, point potential, point velocity) {
    particle new_particle = { .radius = radius, .pos = pos, .potential = potential, .velocity = velocity };
    return(new_particle);
}
trough initTrough(particle particles[]) {
    int num = sizeof(particles) / sizeof(int) + 1;
    trough new_trough = { .num = num, .particles = particles };
    return(new_trough);
}
experiment initExperiment(trough in_trough) {
    experiment new_experiment = { .trough = in_trough };
    return(new_experiment);
}

/** probs **/
experiment newExperiment() {
    particle new_part1 = initParticle(1, initPoint(0, 4, 0), initPoint(0, 0, 0), initPoint(0, 0, 0));
    particle new_part2 = initParticle(1, initPoint(4, 4, 0), initPoint(0, 0, 0), initPoint(0, 0, 0));

    printPoint(new_part1.pos);
    printPoint(new_part2.pos);

    particle particles[2] = { new_part1, new_part2 };
    trough new_trough = initTrough(particles);

    printPoint(new_trough.particles[0].pos);
    printPoint(new_trough.particles[1].pos);

    return(initExperiment(new_trough));
}
int main(int argc, char *argv[]) {
    experiment experiment = newExperiment();

    printPoint(experiment.trough.particles[0].pos);
    printPoint(experiment.trough.particles[1].pos);

    return(0);
}

我编译代码:gcc -lm -std=c99 -Wall main.c并运行它:./a.out,并获得以下输出:

$ ./a.out
0.000000, 4.000000, 0.000000
4.000000, 4.000000, 0.000000
0.000000, 4.000000, 0.000000
4.000000, 4.000000, 0.000000
0.000000, 4.000000, 0.000000
0.000000, 4.000000, 0.000000

问题是输出的最后一行,我试图找到粒子数组中一个点的x,y,z值 - 我在代码中所做的只是在各个点打印值,并且所以价值观不应该改变 - 但它们是,而且我很困惑为什么会这样。这是否与索引引用数组有关?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您忘记在槽结构中分配粒子。有几种方法可以做到这一点。在您的示例中,修复是使粒子成为两个元素的数组:

typedef struct {
    int num;                // size of particle array
    particle particles[2];
};

而不是particals-pointer(在你的例子中指向“无处”)。

当然,您需要为您的应用选择正确的数据结构。列表,定义大小的数组或分配的数组等。

答案 1 :(得分:1)

类型trough不包含particle的数组。它包含一个指向particle s数组的指针。您初始化它以指向newExperiment()中声明的函数局部数组。

但是当函数newExperiment结束时,数组的生命周期结束,并尝试再次使用main中的悬空指针导致未定义的行为。

如果粒子数有最大编译时间,则可以将指针成员更改为数组成员,如@Patrick B所示。如果没有,您将需要使用mallocfree来确保指针成员指向内存,只要您需要它就会保持有效。