I’m attempting to write a colloidal simulation program in C, and I came across a curious issue that I do not know how to resolve – I’ve reduced the code to the minimum where it shows the same type of error. (I’m sorry ahead of time for the length of the code…)
/** 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);
}
I compile the code: gcc -lm -std=c99 -Wall main.c and run it: ./a.out, and get the following output:
$ ./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
The problem is the last line of output, where I was trying to find the x, y, z values of a point in the array of particles – all I did in the code was to print the values at various points, and so the values shouldn’t be changing – but they are, and I’m quite confused as to why this is. Would this have to do with referencing the array by index? Any help would be greatly appreciated.
Type
troughdoes not contain an array ofparticles. It contains a pointer which can point at an array ofparticles. You initialized it to point at the function-local array declared innewExperiment().But when function
newExperimentends, the array’s lifetime ends, and trying to use that dangling pointer again frommaincauses Undefined Behavior.If there’s a known compile-time maximum to the number of particles, you can change the pointer member to an array member as @Patrick B showed. If not, you’ll need to use
mallocandfreeto make sure the pointer member points at memory which will remain valid as long as you need it to.