2011-04-05 158 views
2

我正在創建簡單的粒子系統。我有兩個typedef結構。首先代表具有一些場的單個粒子。第二個代表粒子系統。我的問題是我無法爲每個Particle分配內存。真的不知道什麼是錯的。 下面是結構:無法釋放指向先前分配的結構的指針

typedef struct { 
    float m; 
    float *x; 
    float *v;  
    float *f;  
    float R; 
} *Particle; 

typedef struct { 
    Particle *p; 
    int n; 
    float t; 
} *ParticleSystem; 

和這裏代碼分配

ParticleSystem sys = (ParticleSystem) malloc(sizeof(ParticleSystem)); 
sys->p = (Particle *) malloc(sizeof(Particle)*noOfParticles); 

for(int i=0;i<noOfParticles;i++){ 
    sys->p[i] = (Particle)malloc(sizeof(Particle)); 

    sys->p[i]->f = (float*)malloc(sizeof(float)*2); 
    sys->p[i]->f[0] = 0.0f; 
    sys->p[i]->f[1] = 0.0f; 

    ... 

    sys->p[i]->R = radius; 
    sys->p[i]->m = mass; 

} 

sys->n=noOfParticles; 
sys->t = 0.0f; 

和釋放

int n = sys->n; 
for(int i=0;i<n;i++){ 
    free(sys->p[i]->f); 

    ... 

    free(sys->p[i]);//here it breaks 
} 
free(sys->p); 
free(sys); 

在線「免費(SYS-> P [I])它打破我。不知道爲什麼,因爲首先我這樣做
sys-> p [i] =(Particle)malloc(sizeof(Particle))來分配Visual Studio中的「HEAP [template.exe]:無效的地址sp ecified到RtlValidateHeap(01E70000,01E749B0) Windows已經引發了template.exe一個斷點。」

+0

C++或C?選一個。 – 2011-04-05 16:19:20

+0

抱歉選擇C和C++。它應該是C. – pchot 2011-04-05 16:38:52

回答

4

作出這樣的類型定義,當我不使用星號。當malloc'ing內存和使用指針時,這很容易導致很多混淆。只需使用

typedef struct { 
    float m; 
    float *x; 
    float *v;  
    float *f;  
    float R; 
} Particle; 

這將使它更清晰,我甚至不知道哪些行爲你的typedef原因(你可能只是一個指針ALLOC空間)

只要看看行那些2線:

sys->p = (Particle *) malloc(sizeof(Particle)*noOfParticles); 
sys->p[i] = (Particle)malloc(sizeof(Particle)); 

我假設你想獲得內存在首位的指針和內存比對結構本身在第二位。但這項工作應該如何?你在兩個malloc中使用sizeof(Particle)。

+0

謝謝,就是這樣。但我認爲這樣會更有效 – pchot 2011-04-05 16:32:28

+0

一個提示:如果你想鍵入一個指針,使用2 typedefs:一個用於結構,一個用於指針:typedef struct {char \ * string; int a;雙b; } myStruct; typedef myStruct \ * myStructPointer; – Chris 2011-04-06 07:15:06

5

這已經有一段時間,因爲我做了C/C++編程,但不要那些typedef的聲明Particle爲類型指針指向那個結構和ParticleSystem是類型指針的那個其他結構?如果是這樣,當你分配內存時,你只分配足夠的內存來存放指針,而不是實際的結構。

例如:

#include <iostream> 

using namespace std; 

typedef struct { 
    float m; 
    float *x; 
    float *v; 
    float *f; 
    float R; 
} *Particle; 

typedef struct { 
    Particle *p; 
    int n; 
    float t; 
} *ParticleSystem; 

int main() 
{ 
    cout << "sizeof(Particle) = " << sizeof(Particle) << endl; 
    cout << "sizeof(ParticleSystem) = " << sizeof(ParticleSystem) << endl; 
    return 0; 
} 

,當我運行該程序,我得到:

sizeof(Particle) = 4 
sizeof(ParticleSystem) = 4 
+0

什麼是「C/C++編程」? – 2011-04-05 16:19:39

+3

「C或C++編程」的速記 – QuantumMechanic 2011-04-05 16:21:00

+0

與流行信仰™相反,C不是C++的子集。 – tiftik 2011-04-05 16:22:58

1

嘗試改變:

typedef struct { 
float m; 
float *x; 
float *v;  
float *f;  
float R; 
} *Particle; 

typedef struct { 
float m; 
float *x; 
float *v;  
float *f;  
float R; 
} Particle; 

你需要有一個Particle纔能有一個*Particle,爲了有sizeof(Particle)工作......這同樣適用於ParticleSystem

1

我將開始通過結構聲明固定:

} Particle; 

} ParticleSystem; 

而不是指針。

,然後更新的代碼的其餘部分,以反映這一變化,開始:

ParticleSystem* sys = (ParticleSystem*) malloc(sizeof(ParticleSystem)); 
sys->p = (Particle*) malloc(sizeof(Particle) * noOfParticles); 
4

如果這是C,那麼您確實不應該輸入malloc()的返回值。如果這是C++,那麼你真的不應該使用malloc()

此外,我建議不要typedef:指出你的指針,這使得它很難跟蹤代碼和發現錯誤。

此外,如果您知道數組總是具有恆定的小尺寸(如兩個)(Particle.f以此方式使用),則使用malloc()沒有意義。只需直接聲明一個數組,並保存在malloc()和相關的混淆。

0

首先,您有Particle *p,您可以將其分配爲單個粒子或粒子數組。

你正在第二行分配* p作爲數組,所以你不能在for循環中再次分配它們,除非你使用Particle **p然後把*(p)作爲數組os指向Particle,然後你在for循環中分配每個粒子。我不推薦。

如上所述,從結構中刪除指針聲明。

然後,你不必重新分配每個粒子(因爲p是一個普通的指針),你應該只用free(sys->p);釋放它,因爲你將每個單個粒子作爲一個直接的位置分配給記憶,而不是指針,正如我所說的那樣。

希望它有幫助:)