2011-11-01 65 views
0

我試圖在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值 - 我在代碼中所做的一切就是在各個點上打印值,所以值不應該改變 - 但他們是,我很困惑,爲什麼這是。這是否與通過索引引用數組有關?任何幫助將不勝感激。

+0

此外,'sizeof(particles)'不會做你的想法,因爲函數參數永遠不會有數組類型。即使你寫了'通過初始槽(粒子粒子[])',粒子的類型是'粒子*'。該聲明可能應該是'trough initTrough(int num,const particle * particles)'。 – aschepler

回答

1

類型trough不包含particle s的數組。它包含一個可以指向particle的數組的指針。您將其初始化爲指向newExperiment()中聲明的函數本地數組。

但是,當函數newExperiment結束時,數組的壽命結束,並試圖從main再次使用該懸掛指針導致未定義的行爲。

如果粒子的數目已知最大編譯時間,則可以按@Patrick B所示將指針成員更改爲數組成員。如果不是,則需要使用mallocfree以確保指針成員指向內存,只要您需要,該內存將保持有效。

2

你忘了在你的槽結構中分配粒子。有幾種方法可以這樣做。在您的示例的解決方法是使粒子兩個元素的數組:

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

代替particals指針(其指向「無處」在你的例子)。

當然,您需要爲您的應用程序選擇正確的數據結構。列表,已定義大小的數組或已分配的數組等。

相關問題