Struct array memory layout of the elements

AI Thread Summary
The discussion focuses on computing the memory layout of a struct array in C, specifically for a struct named `Person` containing a character array, an integer, and a float. The initial address of the first element is given as 0x0012FF1A, and participants clarify that the size of each `Person` struct is 28 bytes (0x1C in hex). It is confirmed that to find the addresses of subsequent elements, one can add 0x1C to the previous address, but caution is advised regarding compiler optimizations that may affect memory alignment. Additionally, the importance of using specific data type definitions for portability across platforms is emphasized. The thread concludes with a suggestion to verify the computed addresses using a compiler.
Sumaya
Messages
29
Reaction score
0
hi every one ,

i am new in data structure course

i need help in this :

Code:
Struct Person 
{
Char name[20];
int id;
float gpa;
};
Person student[5];

Compute the addresses of all the elements of array student and show a memory layout for the array if the address of the first element is 0x0012FF1A.

some what i did :
i did account that there is 28 bytes = 1c in hex
and i know that i have to add 1C to the address 0x0012FF1A and i think i'll get 0x0012FF36

my problem is if the first address 0x0012FF1A is the address for the first byte student[0]

so should i keep adding 1C to the previous address until i arrive to student[5]

just wondering and also how it is look like the memory layout . is there 28 bytes between every array like between student[0] and student[1]

thanx alot
 
Last edited by a moderator:
Technology news on Phys.org
First note that most compilers by default put each member on a word or long boundary, especially if you have speed optimization enabled. You can override that with certain compiler directives (like 'pack') or command line options. However it looks like each member in that struct is already a multiple of longs, so it should already be packed.

student[0] is a struct.
&student[0] is the address of the first struct.
student[4] is the last element (not student[5].

But in answer to your question, yes you can add 0x1C to iterate the elements but only if you know they are packed (and I think they are from the size of them) but sometimes compilers optimize in strange ways, so be careful. using sizeof should be useful.
 
On top of what fleem said above, if you want to use absolute alignment (i.e. byte alignment and not word alignment), you need to tell the compiler, and that often means using a compiler directive.

For MSVC, I think it is a pragma macro (pack maybe?).

Also you should not use definitions like int or float directly. Create an include file that guarantee's data structures to be of a specific type. Use things like INT32 or UINT32 where that definition absolutely has a guarantee that the particular data type, no matter what platform is used is in fact a 32 bit signed or unsigned integer. When the platform is different, just add a compiler directive and then based on that write the appropriate typedef to force it to the right data type.
 
thanx a lot for every one ...
 
The syntax is not quite right you either want:

Code:
struct Person 
{
char name[20];
int id;
float gpa;
};

struct Person student[5];

or

Code:
typedef struct
{
char name[20];
int id;
float gpa;
}Person;

Person student[5];

Compute the addresses of all the elements of array student and show a memory layout for the array if the address of the first element is 0x0012FF1A.
I'm assuming you've completed this assignment. If you have access to a compiler you can check your answers, by declaring 0x0012FF1A to be a pointer to the structure, then printing out the addresses of the elements of an array of these structures. A pointer to an object can be indexed, in which case the compiler assumes the pointer is the address of the first object in an array of objects.

Code:
#include <stdio.h>

typedef struct
{
char name[20];
int id;
float gpa;
}Person;

int main()
{
int i;
    for(i = 0; i < 5; i++){
        printf("adr person[%d].name = %x\n", i, &((Person *)(0x0012FF1A))[i].name);
        printf("adr person[%d].id   = %x\n", i, &((Person *)(0x0012FF1A))[i].id);
        printf("adr person[%d].gpa  = %x\n", i, &((Person *)(0x0012FF1A))[i].gpa);
    }
    return(0);
}
 
Last edited:
I just happened to re-read this thread and thought of something else that should be mentioned in case you are doing it but didn't mention it in your post. That something is how pointer arithmetic works in C/C++. When you add a value to a pointer, the compiler actually adds that many structure sizes to the pointer, instead, because it assumes you are working with an array of those structures. for example, if you have a pointer to a structure of size 7, then adding a 3 to it will really be like adding a 21 to it.
 
fleem said:
... how pointer arithmetic works in C/C++. When you add a value to a pointer, the compiler actually adds that many structure sizes to the pointer, instead, because it assumes you are working with an array of those structures. for example, if you have a pointer to a structure of size 7, then adding a 3 to it will really be like adding a 21 to it.
You can also use an index with the pointer, as shown in the code fragment in my previous post where I delcare 0x0012FF1A to be a pointer to Person, then index that pointer ( ... ).
 
Last edited:
Back
Top