2014-03-27 54 views
0

我在C以下代碼:如何在C中分配不同類型的內存?

typedef struct 
{ 
    int age; 
    int phoneNumber; 
} Student; 

typedef struct 
{ 
    int id; 
    int student[1]; 
} People; 

#define NUM_OF_PEOPLE 
void *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE); 

我怎麼能找到指針存儲點的struct Student在內存中的第一個元素?

我嘗試這樣做以下列方式:

int i = 0; 
for(i = 0; i < NUM_OF_PEOPLE; i++) 
{ 
    Student * student_p = p.student[NUM_OF_PEOPLE]; 
} 

它不工作,所以我們可以在路上分配內存?
以及如何在內存中找到struct Student的第一個元素?

+0

[這個答案](http://stackoverflow.com/questions/20221012/unsized-array-declaration-in-a-struct/20221073#20221073)是我使用靈活數組成員的一個很好的例子。 –

+0

爲什麼不在'People'中有一個'Student'數組? – Brian

+0

好吧,結構不能改變 – ratzip

回答

1

你有一個古老的靈活的陣列成員的方式,這在技術上也是未定義的行爲。

您正在尋找this

首先,你需要像這樣定義你的結構(我不知道是什麼Studentsints的,所以我們就稱它爲ID):

typedef struct 
{ 
    int age; 
    int phoneNumber; 
} Student; 

typedef struct 
{ 
    int id; 
    Student student; 
} StudentAndId; 

typedef struct 
{ 
    int id; 
    StudentAndId students[]; 
} People; 

注意在缺少大小數組內People。現在,你這樣做:

People *p = malloc(sizeof(People) + sizeof(StudentAndId[NUM_OF_PEOPLE])); 

然後你就可以訪問studentsp彷彿這是NUM_OF_PEOPLE元素的數組。


記得用C99(或C11)支持進行編譯。用gcc將是-std=c99-std=gnu99

+0

不明白,你的意思是這不起作用? – ratzip

+0

@ratzip,它可能,但正確的語法有點不同。我會爲你寫一個例子。 – Shahbaz

0

這將分配內存來存儲日期,但您如何訪問它取決於您如何存儲日期。使用C指針可以使用這種結構和分配來存儲和訪問數據,但訪問成員不會是直接的。它將涉及指針算術。如果可能,最好使用其他結構。如果使用這種分配方式,那麼你需要做指針運算來獲得下一個元素。

0

試試這個:

#include <stdio.h> 
#include <stdlib.h> 

typedef struct 
{ 
    int age; 
    int phoneNumber; 
} Student; 

typedef struct 
{ 
    int id; 
    int student[1]; 
} People; 

#define NUM_OF_PEOPLE 10 
int main() 
{ 
    People *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE); 
    int* id = (int*)(p+1); 
    Student* s = (Student*)(id+NUM_OF_PEOPLE); 

    printf("Size of People : %d\n", sizeof(People)); 
    printf("p points to : %p\n", p); 
    printf("id points to : %p\n", id); 
    printf("s points to : %p\n", s); 
} 

下面是一個示例輸出:

 
Size of People : 8 
p points to : 0x80010460 
id points to : 0x80010468 
s points to : 0x80010490 
+0

請注意,這通常不是一個好主意。例如,如果'Student'以'uint64_t'變量開始,並且'sizeof(People)+ sizeof(int)* NUM_OF_PEOPLE'不是8的倍數,那麼最終會得到錯誤對齊的64位變量。 – Shahbaz

0

您可能希望將id字段添加到您的Student數據結構,例如:

typedef struct { 
    int id; 
    int age; 
    int phoneNumber; 
} Student; 

然後,你可以定義一個具有固定標題的結構(在這種情況下,這可以是nu學生MBER),隨後的Student秒的可變大小的數組:

#define ARRAY_OF_ANY_SIZE 1 

typedef struct { 
    int count; 
    Student students[ARRAY_OF_ANY_SIZE]; 
} People; 

This blog post解釋具有「尺寸1的陣列」,包括對準問題的討論的這種技術。

我不會在這裏重複原始的博客帖子代碼。請考慮您可以使用便攜式offsetof()而不是Windows特定的FIELD_OFFSET()宏。

作爲示例代碼,你可能要考慮以下幾點:

#include <stdio.h>  /* For printf()     */ 
#include <stddef.h> /* For offsetof()    */ 
#include <stdlib.h> /* For dynamic memory allocation */ 

typedef struct { 
    int id; 
    int age; 
    int phoneNumber; 
} Student; 

#define ARRAY_OF_ANY_SIZE 1 

typedef struct { 
    int count; 
    Student students[ARRAY_OF_ANY_SIZE]; 
} People; 

int main(int argc, char* argv[]) { 
    People* people; 
    const int numberOfStudents = 3; 
    int i; 

    /* Dynamically allocate memory to store the data structure */ 
    people = malloc(offsetof(People, students[numberOfStudents])); 
    /* Check memory allocation ... */ 

    /* Fill the data structure */ 
    people->count = numberOfStudents; 
    for (i = 0; i < numberOfStudents; i++) { 
     people->students[i].id = i; 
     people->students[i].age = (i+1)*10; 
     people->students[i].phoneNumber = 11000 + i; 
    } 

    /* Print the data structure content */ 
    for (i = 0; i < people->count; i++) { 
     printf("id: %d, age=%d, phone=%d\n", 
       people->students[i].id, 
       people->students[i].age, 
       people->students[i].phoneNumber); 
    } 

    /* Release the memory allocated by the data structure */ 
    free(people); 

    return 0; 
} 

輸出:

id: 0, age=10, phone=11000 
id: 1, age=20, phone=11001 
id: 2, age=30, phone=11002 
+0

是的,但如何分配struct student和一個int數組,然後訪問它並填充數據? – ratzip