2014-03-27 55 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