When you pass/return structures it is desirable to work with their addresses. Do not pass/return structures by value (i will explain why below).
I can not understand what you code should do, but let me give an example that will make you understand how passing structures can be made possible in C
Suppose we have the following structure:
struct tagPerson
{
char FirstName[100];
char LastName[100];
};
typedef struct tagPerson Person; // <-- without this line, Person is just a tag, not a valid datatype
Now, you want to make a function that will return a Person
. This is how:
Person CreatePerson(const char* FirstName, const char* LastName)
{
Person p; // <-- this will create a person.
strcpy (p.FirstName, FirstName); // <-- this is how you copy a string in C
strcpy (p.LastName, LastName);
// and now just return the person.
return p;
}
Inside your main
you can call the CreatePerson
function like this:
int main()
{
Person p = CreatePerson("Alex", "Anderson"); // not great names tho :)
return 0;
}
Now, the CreatePerson
function is not quite good, because it returns a Person
by value. If you check with the sizeof
operator, you can see that sizeof(Person)
is 200 bytes.
Usually, functions in C
and C++
use data registers
to return values and copy values for the function parameters.
The ideal case is when the parameters and the return value fit into a small amount of registers.
In our CreatePerson
function however, the variable p
needs to remain on the stack and (probably) the eax
register will hold its address. The line from main
: Person p = CreatePerson(...);
will be broken down into allocating space on the stack for the new variable p
and copy what lies where eax
points.
The actual explination is much bigger and does not fit your question, so i'll skip it. If you want to learn more about it, google about C/C++ function parameters and registers.
Luckily, the solution is simple. Pass or return object addresses instead. Here is how the CreatePerson
function can be modified to do the same thing, but a lot better in terms of stack memory.
void CreatePerson(Person* p, const char* FirstName, const char* LastName)
{
// You no longer need to declare a person.
// The address where data should be filled with the first and last name
// if provided through the parameter p.
strcpy (p->FirstName, FirstName);
strcpy (p->LastName, LastName);
// you no longer need to return anything.
}
With the above declaration of the function, only space for 3 pointers is necessary (that actually means 12
bytes on x32
or 24
bytes on x64
). You can call it from main
like this using the unary operator &
to pass the address of the variable p
:
int main()
{
// You still need to create a Person instance
// you just do it outside the function.
Person p;
CreatePerson(&p, "Alex", "Anderson"); // not great names again but...
// now just print the name
printf("The person is called %s %s.", p.FirstName, p.LastName);
return 0;
}
Again, i do not know what you wanted to do with your code, but i see no good reason to return structures with the return
keyword. Parameters can also be used in
and out
operations. There is however, one single case where the return
comes in more handy, and that is when you need to dynamically allocate the structure. Suppose we needed person on the heap
and not on the stack
, this is how the CreatePerson
function could have looked:
Person* CreatePerson(const char* FirstName, const char* LastName)
{
// You now need to allocate person on the heap.
Person* p = malloc(sizeof(Person));
strcpy (p->FirstName, FirstName);
strcpy (p->LastName, LastName);
// Return the address where person is allocated
return p;
}
And this is how you now use it in main
:
int main()
{
// You now need a pointer.
Person* p = CreatePerson("Alex", "Anderson");
// Do something with it...
printf("The person is called %s %s.", p->FirstName, p->LastName);
// Now that you are done, free the memory where the person is stored.
free(p);
return 0;
}
Because you are new to C, i'm going to also tell you this:
- You need to include
<stdlib.h>
for malloc()
and free()
.
- You need to include
<stdio.h>
for printf()
- You need to include
<string.h>
for strcpy()