How to Return a Struct From Function in C
- Use Standard Notation to Return a Struct From a Function in C
- Use Pointer Notation to Return a Struct From a Function in C
- Return a Struct by Value in C
-
Return a Struct via
malloc
in C - Return a Struct via a Global Variable in C
- Conclusion
In C programming, structures (or structs) allow you to group different data types under a single name, making it a powerful tool for organizing and managing data.
One common requirement is the need to return a struct
from a function, allowing for the creation of modular and reusable code. This article will demonstrate multiple methods about how to return a struct
from a function in C, along with detailed examples for each method.
Use Standard Notation to Return a Struct From a Function in C
The struct
keyword in C is used to implement user-defined data structures. Since we define the struct
type in this example, it will be a cleaner notation for function declarations if we typedef
the MyStruct
structure.
It will associate a new type alias for the given structure, and we’d need to specify only the new alias name in the function prototype. Now, functions in C can return the struct
similar to the built-in data types.
In the following example code, we implemented a clearMyStruct
function that takes a pointer to the MyStruct
object and returns the same object by value. Note that we need to access struct
members using the ->
operator when the handle is the pointer to the struct
.
#include <stdio.h>
#include <stdlib.h>
enum { DAY = 9, MONTH = 2 };
typedef struct {
int day;
int month;
} MyStruct;
MyStruct clearMyStruct(MyStruct *st) {
st->day = 0;
st->month = 0;
return *st;
}
int setMyStruct(MyStruct *st, int d, int m) {
if (!st) return -1;
st->day = d;
st->month = m;
return 0;
}
int main() {
MyStruct tmp;
if (setMyStruct(&tmp, DAY, MONTH) == -1) exit(EXIT_FAILURE);
printf("day: %d\nmonth: %d\n", tmp.day, tmp.month);
clearMyStruct(&tmp);
printf("day: %d\nmonth: %d\n", tmp.day, tmp.month);
exit(EXIT_SUCCESS);
}
This code defines a structure MyStruct
with integer members day
and month
. It also includes functions to manipulate this structure.
The clearMyStruct
function sets both day
and month
to 0
and returns the modified structure. The setMyStruct
function updates the day
and month
members with provided values, returning 0
on success or -1
if the pointer is invalid.
In main()
, a MyStruct
variable tmp
is created. setMyStruct
is called with arguments &tmp
, DAY
, and MONTH
. If an error occurs, the program exits with a failure status.
The program then prints day
and month
. clearMyStruct
is called to reset the values, which are then printed again.
The program exits with a success status.
Output:
day: 9
month: 2
day: 0
month: 0
Use Pointer Notation to Return a Struct From a Function in C
Generally, struct
defined data structures tend to contain multiple data members, resulting in a big memory footprint. Now, when it comes to passing relatively big structures between functions, it’s best to use pointers.
The pointer serves as a handle to the object, and its size is fixed regardless of the structure stored there. Using pointers to return struct
potentially reduces memory traffic and gives code more performance.
Although the program is compiled with optimization flags, it may implicitly modify the data-passing instructions. Note that we utilized the enum
type to declare named constant integer values.
Example:
#include <stdio.h>
#include <stdlib.h>
enum { DAY = 9, MONTH = 2 };
typedef struct {
int day;
int month;
} MyStruct;
MyStruct *clearMyStruct2(MyStruct *st) {
st->day = 0;
st->month = 0;
return st;
}
int setMyStruct(MyStruct *st, int d, int m) {
if (!st) return -1;
st->day = d;
st->month = m;
return 0;
}
int main() {
MyStruct tmp;
if (setMyStruct(&tmp, DAY, MONTH) == -1) exit(EXIT_FAILURE);
printf("day: %d\nmonth: %d\n", tmp.day, tmp.month);
clearMyStruct2(&tmp);
printf("day: %d\nmonth: %d\n", tmp.day, tmp.month);
exit(EXIT_SUCCESS);
}
This code defines a structure MyStruct
with two integer members: day
and month
. It also includes two functions.
The setMyStruct
function takes a pointer to a MyStruct
(st
) along with integer values for day
and month
. It checks if the pointer is valid and then assigns the provided values to the struct’s members. If successful, it returns 0
; otherwise, it returns -1
.
The clearMyStruct2
function takes a pointer to a MyStruct
(st
) and sets both day
and month
to 0
. It then returns the same pointer.
In main
, a local MyStruct
variable called tmp
is created. The setMyStruct
function is called to set its day
to 9
and month
to 2
.
If the operation fails (due to a null pointer), the program exits with a failure status. The values are then printed.
Next, clearMyStruct2
is called with a pointer to tmp
. This sets both day
and month
to 0
.
The updated values are then printed. Finally, the program exits with a success status.
Output:
day: 9
month: 2
day: 0
month: 0
Return a Struct by Value in C
Returning a struct by value means that a function generates a copy of the entire struct and passes it back to the caller. This approach is straightforward and effective for small or moderately sized structs.
In the example below, the function returnStructByValue
returns a struct directly. This works well for small structs, but it can be inefficient for larger ones due to the memory overhead associated with copying the entire struct.
#include <stdio.h>
// Define a simple struct
struct Point {
int x;
int y;
};
// Function to return a struct by value
struct Point returnStructByValue() {
struct Point p = {3, 4};
return p;
}
int main() {
struct Point result = returnStructByValue();
printf("Result: (%d, %d)\n", result.x, result.y);
return 0;
}
This code begins by including the standard input/output library (stdio.h
). Then, a simple struct named Point
is defined, consisting of two integer members: x
and y
.
Following this, a function named returnStructByValue
is declared. This function returns a struct Point
by value.
Inside the function, a local variable p
of type struct Point
is created and initialized with the values 3
and 4
. The function then returns this struct using the return
statement.
In the main
function, a variable named result
of type struct Point
is declared. The returnStructByValue
function is called, and the returned struct is assigned to result
.
Finally, the values of result.x
and result.y
are printed using printf
.
Output:
Result: (3, 4)
It is worth noting that for larger or more complex structs, alternative methods like returning via pointers or dynamic memory allocation may be more appropriate to ensure efficient memory usage.
Return a Struct via malloc
in C
malloc
stands for “memory allocation”. It is a standard C library function that allows you to dynamically allocate memory at runtime.
This means you can request memory as your program runs and free it when it’s no longer needed.
The malloc
function returns a pointer to the allocated memory block, which you can use to store data. It’s a fundamental tool for managing memory efficiently in C programs.
Syntax:
void* malloc(size_t size);
Here, size
is the number of bytes to allocate. It returns a pointer to the allocated memory or NULL
if the allocation fails.
In the example below, the function returnStructViaMalloc
dynamically allocates memory for a struct using malloc
. It then sets the values and returns a pointer to the allocated memory.
This approach is useful when you want to return a dynamically allocated struct, but don’t forget to free the memory after use.
#include <stdio.h>
#include <stdlib.h>
// Define a simple struct
struct Point {
int x;
int y;
};
// Function to dynamically allocate and return a struct
struct Point* returnStructViaMalloc() {
struct Point* p = (struct Point*)malloc(sizeof(struct Point));
if (p != NULL) {
p->x = 3;
p->y = 4;
}
return p;
}
int main() {
struct Point* result = returnStructViaMalloc();
if (result != NULL) {
printf("Result: (%d, %d)\n", result->x, result->y);
free(result); // Don't forget to free the memory!
}
return 0;
}
In this code, a struct named Point
is defined, which contains two integer members: x
and y
.
Next, there is a function called returnStructViaMalloc
, which returns a pointer to a Point
struct. Within this function, memory is dynamically allocated using malloc
to create space for a Point
struct.
If the allocation is successful (p
is not NULL
), the values of x
and y
are assigned as 3
and 4
, respectively. Finally, the pointer p
is returned.
In the main
function, a pointer named result
is declared. It is assigned the value returned by returnStructViaMalloc()
, which is a dynamically allocated Point
struct.
Next, there is a check to ensure that the allocation was successful (result
is not NULL
). If so, the values of x
and y
are printed using printf
.
Finally, it is crucial to free the allocated memory using free(result)
to prevent memory leaks.
Output:
Result: (3, 4)
This is an effective way to allocate memory for a struct dynamically and return it from a function while also emphasizing the importance of memory deallocation using free()
.
Return a Struct via a Global Variable in C
In this method, we use a global variable globalResult
to store the result. The function returnStructViaGlobal
modifies this global variable.
While this approach is simple, it can lead to problems in larger programs due to potential conflicts with other parts of the code.
#include <stdio.h>
// Define a simple struct
struct Point {
int x;
int y;
};
// Define a global variable to store the result
struct Point globalResult;
// Function to modify the global variable
void returnStructViaGlobal() {
globalResult.x = 3;
globalResult.y = 4;
}
int main() {
returnStructViaGlobal();
printf("Result: (%d, %d)\n", globalResult.x, globalResult.y);
return 0;
}
In this code, a struct named Point
is defined, containing two integer members: x
and y
.
Following this, a global variable globalResult
of type Point
is declared. This variable will store the result of the function operation.
Next, a function named returnStructViaGlobal
is defined. Within this function, the x
member of globalResult
is assigned the value 3
, and the y
member is assigned the value 4
.
Moving on to the main
function, returnStructViaGlobal()
is called, which updates the values of globalResult
. Finally, a printf
statement is used to display the values of x
and y
stored in globalResult
.
Output:
Result: (3, 4)
This approach is relatively straightforward, but it’s important to be cautious when using global variables as they can lead to potential conflicts and make the code less modular.
Conclusion
Structures in C provide a powerful way to organize data. This article explored multiple methods for returning a struct from a function.
- Standard Notation: Using
typedef
with structs improves code readability and allows functions to return structs like built-in types. - Efficient Memory Management: For large data structures, using pointers can enhance performance. Functions can directly modify struct members through pointers.
- Returning by Value: This method involves creating a copy of the entire struct within a function and passing it back to the caller. It’s efficient for small to moderately sized structs.
- Dynamic Memory Allocation with
malloc
: This allows you to allocate memory for a struct at runtime. Remember to free the memory after use to prevent memory leaks. - Global Variables: While simple, using global variables can lead to potential conflicts and reduce modularity, especially in larger programs. It may be suitable for smaller, well-defined scopes.
By choosing the right method based on your specific needs, you can write more efficient and maintainable C programs.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook