ANSI C do you have to use malloc() when creating a struct? - c

Let's say I have this struct in ANSI C:
typedef struct _point
{
float x;
float y;
} Point;
and this function to create this struct:
Point createpoint(float x, float y)
{
Point p;
p.x = x;
p.y = y;
return p;
}
This allows me to create a struct with this function i.e:
int main()
{
Point pointOne = createpoint(5, 6);
Point pointTwo = createpoint(10, 4);
float distance = calculatedistancefunc(pointOne, pointTwo);
/* ...other stuff */
return 0;
}
Someone told me that this code is not valid, because the struct does not get malloc'd in the createpoint(float x, float y) function before it gets returned, and that the struct will be deleted.
However, when I use my struct like this, it doesn't seem to get deleted.
So my question is:
do I have to malloc this struct, and why? / why not?

Whatever you are doing is entirely correct. The statement -
return p;
in the function returns a copy of the local variable p. But if you want the same object that was created in the function, then you need to malloc it. However, you need to free it later.
Point createpoint(float x, float y)
{
Point p;
p.x = x;
p.y = y;
return p;
} // p is no longer valid from this point. So, what you are returning is a copy of it.
But -
Point* createpoint(float x, float y)
{
Point *p = malloc(sizeof(Point));
p->x = x;
p->y = y;
return p;
}// Now you return the object that p is pointing to.

You can return struct on the stack, your code is valid. A problem would occur if you'd to return a pointer to the local variable, but that's not what you're doing, you're returning a copy, that's fine.

C99 allows for even nicer on-the-stack creation of structs.
Given the below struct
typedef struct
{
float x;
float y;
} Point;
you can initialize it in a bit of a C++ constructor style manner with the following statement:
Point p = (Point){0.4, 0.5};
and thus you could either shorten your createpoint or scrap it altogether:
int main()
{
Point pointOne = (Point){5, 6};
Point pointTwo = (Point){10, 4};
float distance = calculatedistancefunc(pointOne, pointTwo);
//...other stuff
return 0;
}

Point createpoint(float x, float y)
{
Point p;
p.x = x;
p.y = y;
return p;
} /
All local variables in function are deleted after function returns.
1> pass by reference
So if you are returning pointer to this local variable then after function return this variables are deleted so that pointers are invalid.
2> pass by value
But here you are returning copy of this local variable so its safe because that local variable are gona dead when function returns but the copy of return value will be stored in receiver variable in function call before function return.

A call to a method which returns a structure will behave as though the caller creates a temporary variable of the structure type somewhere which isn't visible in any other scope, and gives the called function a pointer to it. The called function will then put the data in the requested place, and after it returns the caller will be able to read the data from its new variable. Given a function and calling code:
StructType BuildStruct(void)
{
StructType it;
it.this=4;
it.that=23;
return it;
}
StructType myStruct;
myStruct = BuildStruct();
it's likely that there will be at least one copy operation if not two; the statement return it; may need to copy from local variable it to the temporary struct, and the assignment to myStruct may need to copy from the temporary location to myStruct. No situation actually requires two copy operations; some require one (which could be performed by the caller or by the called method) and some require none, but the necessity of copying is dependent upon details in both the caller and the called method.
An alternative design would be:
void BuildStruct(StructType *it)
{
it->this=4;
it->that=23;
}
StructType myStruct;
BuildStruct(&myStruct);
That would likely yield code equivalent to the best code one could hope for using a structure-type return variable, since the struct data would be placed directly into its final spot without any structure copying being necessary.

Related

Is there a way to make a variable survive 1 scope out of the current one?

I want to make a function that returns a pointer to a locally-defined variable. For the sake of argument, I'll call the function struct awesome *makeCoolStruct() (I don't want to declare the variable in the outer scope which should have the call struct awesome coolness = makeCoolStruct(); because the function will be called in more than one place).
I understand why the compiler errors out when I try doing that - the local variable will be 'destroyed' as soon as the program exits that scope, so the pointer will basically be invalid.
I looked up how to return a pointer to a local variable in a function, and while I get why malloc would work, that defeats the purpose of trying to do it this way, because malloc, as far as I understand, keeps the variable for as long as the program runs - or until free is called. However, that means that I'll have to have free called at the end of anything that calls my function. At that point, I'd be better off declaring the variable in every calling scope and then passing a pointer to it like makeCoolStruct(&existingVariable);.
If, however, there's a way to declare "keep this variable for 1 position higher in the stack" (which would obviously produce a compilation error in the global scope since there are no higher positions in the stack), then I could return a pointer and it'll exist just fine for as long as I need it to, wherever I decide to call struct awesome x = makeCoolStruct(); (I'm aware of the mutability issues - I'm not looking for mutability). I could truly return anything I want in a function from that point on, not just stuff that was passed in.
I haven't really tried anything because I don't know of anything that would work.
I expect to be able to return a pointer to a local variable after doing whatever keeps the variable for one scope higher, without having to do any preparations for the function call when I call it (creating a variable for it to use for the output instead of just assigning the output to something.
What you're asking isn't possible in C, but here are some alternatives:
Passing a stack variable in:
typedef struct {
int a;
int b;
} Foo;
void bar(Foo* foo)
{
foo->a = 5;
}
int main(void)
{
Foo foo = {0};
bar(&foo);
return 0;
}
Returning the struct directly:
Foo bar(void)
{
Foo foo = {1, 2};
return foo;
}
int main(void)
{
Foo foo = bar();
return 0;
}
Managing the memory manually:
Foo* bar(void)
{
Foo* foo = malloc(sizeof(*foo));
return foo;
}
int main(void)
{
Foo* foo = bar();
free(foo);
return 0;
}
Lastly, if you really hate whoever is going to inherit this project, you could always use a macro:
#define FOO(X) \
Foo X = {0}; \
bar(&X);
Although not recommended, it is actually safe to return a pointer to a static variable, assuming your program is not multithreaded.
struct myStruct {
int x;
char y;
};
struct myStruct *foo()
{
static struct myStruct bar = {.x = 0, .y = 'a'};
return &bar;
}
I would never write something like that, but it is safe in the sense that it does not invoke undefined behavior.
And just in case you did not know, it's perfectly cool to return a struct. You don't need malloc for that. This would be fine:
struct myStruct foo()
{
struct myStruct bar = {.x = 0, .y = 'a'};
return bar;
}

Return a structure with const array in C

Is it safe to return a struct with array data member in C?
Something like
struct my_str {
int v[5];
};
struct my_str ret_stupid() {
struct my_str rval;
/*do something..*/
return rval;
}
I don't know why... I'm a bit puzzled. (I've tried and it does work). Is there some standard explaining how this operation actually is performed? I mean the mechanism of struct return and assignment too could be useful to understand better.
Is it safe to return a struct with array data member in C?
Yes.
struct are copied bit-wise. Bit-wise copying a struct that has an array as a member makes sure that the copy of struct has a copy of the array too.
Structures are a lot like arrays.
They can contain variables of any kind.
Their addresses will be sorted stacked as long as you leave no gaps or invoke the preprocessor directive #pragma pack
"Is it safe", depends of the code hiding there..
/do something../
But in general - yes. This is just a function of type struct my_str and has to return struct my_str
What the structure contains - doesn't matter. Still safe to use.
You can return a structure from a function without any problems. It's a well-defined part of the language. You can pass structures to functions as well - a structure is exactly the same as any built-in type for purposes of parameter passing, return values, and assignment.
Here's an example
#include <stdio.h>
int func(int x)
{
int r = x;
return r;
}
int main(void)
{
int x = 12;
int y = func(x);
printf("%d\n", y);
return 0;
}
If it weren't for the array member, the return would be an "rvalue", a value that is just a copy of the value that you have inside the return expression. If you have
struct toto {
double a;
};
struct toto g(void) {
struct toto retval = { 0.0 };
...
return retval;
}
int main(void) {
printf("%g\n", g().a);
}
The argument of the printf call sees a copy of the variable retval that is used inside the function. g().a calls the function and uses the .a field of the return value.
This return value is and
entity that is not an object but only lives because of its "value", called rvalue in the C jargon. It only can be found on the RHS of an assignment, thus the "r" in "rvalue".
The case that you are giving is actually specially treated, because a "value" is not sufficient for all use cases of the array. So this generates a so-called "object with temporary lifetime". This is needed because if you'd do ret_stupid().v[2] the [] operator wants to have a pointer, and a pointer can only point to an object, not a value.
These objects only "live" inside the expression that contains the function call, and even though they are not const qualified you are not allowed to modify them.
So all in all, this is a corner case of C, and you shouldn't abuse it.

Structure returning function

In C component selection, what is the benefit of structure-returning function? for example:
struct S {
int a, b;
} x;
Why is it that I can assign the above struct as a function as shown below, Is there any benefit of doing this?
extern struct S f(); /* Why is this neccesary? */
x = f(); /* Is this accurate */
Open my eyes on this guys.
It's just a function that happens to return a struct. There's nothing more to it than that. You wouldn't be surprised to see a function return an int, why be surprised when one returns a struct?
As an aside, the extern is superfluous here because that is the default storage class for functions.
It is useful so that you can return multiple values from a function.
For example, you can use it like this
struct Point {
int x;
int y;
};
struct Point getMousePos()
{
struct Point pos;
pos.x = 567;
pos.y = 343;
return pos;
}
int main()
{
struct Point mouse_pos = getMousePos();
printf("Mousepos %d,%d\n", mouse_pos.x, mouse_pos.y");
}
The function can be forward declared with extern (this would normally be done in a header file), so that other functions know its prototype i.e. its parameters and return type, even if the function is itself defined in another file.
If you get a copy of a struct instead of a pointer to it, you know that you never have to worry about free()ing it, or whether there are any data races where one thread is writing to the struct while another reads from it, or whether the pointer returned by the function will be invalidated by some action that might be outside of your control.

Return a `struct` from a function in C

Today I was teaching a couple of friends how to use C structs. One of them asked if you could return a struct from a function, to which I replied: "No! You'd return pointers to dynamically malloced structs instead."
Coming from someone who primarily does C++, I was expecting not be able to return structs by values. In C++ you can overload the operator = for your objects and makes complete sense to have a function to return your object by value. In C, however, you do not have that option and so it got me thinking what the compiler is actually doing. Consider the following:
struct MyObj{
double x, y;
};
struct MyObj foo(){
struct MyObj a;
a.x = 10;
a.y = 10;
return a;
}
int main () {
struct MyObj a;
a = foo(); // This DOES work
struct b = a; // This does not work
return 0;
}
I understand why struct b = a; should not work -- you cannot overload operator = for your data type. How is it that a = foo(); compiles fine? Does it mean something other than struct b = a;? Maybe the question to ask is: What exactly does the return statement in conjunction to = sign do?
You can return a structure from a function (or use the = operator) without any problems. It's a well-defined part of the language. The only problem with struct b = a is that you didn't provide a complete type. struct MyObj b = a will work just fine. You can pass structures to functions as well - a structure is exactly the same as any built-in type for purposes of parameter passing, return values, and assignment.
Here's a simple demonstration program that does all three - passes a structure as a parameter, returns a structure from a function, and uses structures in assignment statements:
#include <stdio.h>
struct a {
int i;
};
struct a f(struct a x)
{
struct a r = x;
return r;
}
int main(void)
{
struct a x = { 12 };
struct a y = f(x);
printf("%d\n", y.i);
return 0;
}
The next example is pretty much exactly the same, but uses the built-in int type for demonstration purposes. The two programs have the same behaviour with respect to pass-by-value for parameter passing, assignment, etc.:
#include <stdio.h>
int f(int x)
{
int r = x;
return r;
}
int main(void)
{
int x = 12;
int y = f(x);
printf("%d\n", y);
return 0;
}
When making a call such as a = foo();, the compiler might push the address of the result structure on the stack and passes it as a "hidden" pointer to the foo() function. Effectively, it could become something like:
void foo(MyObj *r) {
struct MyObj a;
// ...
*r = a;
}
foo(&a);
However, the exact implementation of this is dependent on the compiler and/or platform. As Carl Norum notes, if the structure is small enough, it might even be passed back completely in a register.
The struct b line doesn't work because it's a syntax error. If you expand it out to include the type it will work just fine
struct MyObj b = a; // Runs fine
What C is doing here is essentially a memcpy from the source struct to the destination. This is true for both assignment and return of struct values (and really every other value in C)
As far as I can remember, the first versions of C only allowed to return a value that
could fit into a processor register, which means that you could only return a pointer to
a struct. The same restriction applied to function arguments.
More recent versions allow to pass around larger data objects like structs.
I think this feature was already common during the eighties or early nineties.
Arrays, however, can still be passed and returned only as pointers.
There is no issue in passing back a struct. It will be passed by value
But, what if the struct contains any member which has a address of a local variable
struct emp {
int id;
char *name;
};
struct emp get() {
char *name = "John";
struct emp e1 = {100, name};
return (e1);
}
int main() {
struct emp e2 = get();
printf("%s\n", e2.name);
}
Now, here e1.name contains a memory address local to the function get().
Once get() returns, the local address for name would have been freed up.
SO, in the caller if we try to access that address, it may cause segmentation fault, as we are trying a freed address. That is bad..
Where as the e1.id will be perfectly valid as its value will be copied to e2.id
So, we should always try to avoid returning local memory addresses of a function.
Anything malloced can be returned as and when wanted
yes, it is possible we can pass structure and return structure as well. You were right but you actually did not pass the data type which should be like this struct MyObj b = a.
Actually I also came to know when I was trying to find out a better solution to return more than one values for function without using pointer or global variable.
Now below is the example for the same, which calculate the deviation of a student marks about average.
#include<stdio.h>
struct marks{
int maths;
int physics;
int chem;
};
struct marks deviation(struct marks student1 , struct marks student2 );
int main(){
struct marks student;
student.maths= 87;
student.chem = 67;
student.physics=96;
struct marks avg;
avg.maths= 55;
avg.chem = 45;
avg.physics=34;
//struct marks dev;
struct marks dev= deviation(student, avg );
printf("%d %d %d" ,dev.maths,dev.chem,dev.physics);
return 0;
}
struct marks deviation(struct marks student , struct marks student2 ){
struct marks dev;
dev.maths = student.maths-student2.maths;
dev.chem = student.chem-student2.chem;
dev.physics = student.physics-student2.physics;
return dev;
}
You can assign structs in C. a = b; is valid syntax.
You simply left off part of the type -- the struct tag -- in your line that doesn't work.
struct emp {
int id;
char *name;
};
struct emp get() {
char *name = "John";
struct emp e1 = {100, name};
return (e1);
}
int main() {
struct emp e2 = get();
printf("%s\n", e2.name);
}
works fine with newer versions of compilers.
Just like id, content of the name gets copied to the assigned structure variable.
struct var e2 address pushed as arg to callee stack and values gets assigned there. In fact, get() returns e2's address in eax reg. This works like call by reference.
#include <stdio.h>
struct emp {
int id;
char *name; /* This must point to valid memory, or replace with an array that holes the data, like this char name[128] */
};
struct emp bad() {
static char name[] = {'J', 'o', 'h', 'n', '\0'}; /* static enforces this array to be stored globally and not in the local stack which would not be valid after the function returns */
struct emp e1 = {404, name};
return (e1);
}
int main() {
struct emp e2 = bad();
printf("%s\n", e2.name);
}

Pass struct by reference in C

Is this code correct? It runs as expected, but is this code correctly using the pointers and dot notation for the struct?
struct someStruct {
unsigned int total;
};
int test(struct someStruct* state) {
state->total = 4;
}
int main () {
struct someStruct s;
s.total = 5;
test(&s);
printf("\ns.total = %d\n", s.total);
}
Your use of pointer and dot notation is good. The compiler should give you errors and/or warnings if there was a problem.
Here is a copy of your code with some additional notes and things to think about so far as the use of structs and pointers and functions and scope of variables.
Note: A code writing difference in the source example below is I put a space after the struct name and before the asterisk in the function definition/declaration as in struct someStruct *p1; and the OP put a space after the asterisk as in struct someStruct* p1;. There is no difference to the compiler, just a readability and habit difference for the programmer. I prefer putting the asterisk next to the variable name to make clear the asterisk changes the variable name it is next to. This is especially important if I have more than one variable in a declaration or definition. Writing struct someStruct *p1, *p2, var1; will create two pointers, p1 and p2, and a variable, var1. Writing struct someStruct* p1, p2, var1; will create single pointer, p1 and two variables p2 and var1
// Define the new variable type which is a struct.
// This definition must be visible to any function that is accessing the
// members of a variable of this type.
struct someStruct {
unsigned int total;
};
/*
* Modifies the struct that exists in the calling function.
* Function test() takes a pointer to a struct someStruct variable
* so that any modifications to the variable made in the function test()
* will be to the variable pointed to.
* A pointer contains the address of a variable and is not the variable iteself.
* This allows the function test() to modify the variable provided by the
* caller of test() rather than a local copy.
*/
int test(struct someStruct *state) {
state->total = 4;
return 0;
}
/*
* Modifies the local copy of the struct, the original
* in the calling function is not modified.
* The C compiler will make a copy of the variable provided by the
* caller of function test2() and so any changes that test2() makes
* to the argument will be discarded since test2() is working with a
* copy of the caller's variable and not the actual variable.
*/
int test2(struct someStruct state) {
state.total = 8;
return 0;
}
/*
* Make a local copy of the argument then modify the local copy.
* Until the assignment of the local copy to the argument is made,
* the changes to the local copy are not made to the argument.
* To make any changes made to the local copy in the argument,
* you need to assign the local copy to the argument.
*/
int test3(struct someStruct *state) {
struct someStruct stateCopy;
stateCopy = *state; // make a local copy of the struct
stateCopy.total = 12; // modify the local copy of the struct
*state = stateCopy; /* assign the local copy back to the original in the
calling function. Assigning by dereferencing pointer. */
return 0;
}
int main () {
struct someStruct s;
/* Set the value then call a function that will change the value. */
s.total = 5;
test(&s);
printf("after test(): s.total = %d\n", s.total);
/*
* Set the value then call a function that will change its local copy
* but not this one.
*/
s.total = 5;
test2(s);
printf("after test2(): s.total = %d\n", s.total);
/*
* Call a function that will make a copy, change the copy,
then put the copy into this one.
*/
test3(&s);
printf("after test3(): s.total = %d\n", s.total);
return 0;
}
That's correct usage of the struct. There are questions about your return values.
Also, because you are printfing a unsigned int, you should use %u instead of %d.
Yes, that's right. It makes a struct s, sets its total to 5, passes a pointer to it to a function that uses the pointer to set the total to 4, then prints it out. -> is for members of pointers to structs and . is for members of structs. Just like you used them.
The return values are different though. test should probably be void, and main needs a return 0 at its end.
Yep. It's correct. If it wasn't (from the . / -> point of view), your compiler would yell.
Yes, its correct usage of structures. You can also use
typedef struct someStruct {
unsigned int total;
} someStruct;
Then you won't have to write struct someStruct s; again and again but can use someStruct s; then.

Resources