Seg fault when using structure pointers to access struct members in C - c

What is wrong with my program, I get seg fault when I try to print the values.
My aim is assign some values in sample_function.
and in main function I want to copy the structure to another structure.
#include<stdio.h>
#include<string.h>
typedef struct
{
char *name;
char *class;
char *rollno;
} test;
test *
sample_function ()
{
test *abc;
abc = (test *)malloc(sizeof(test));
strcpy(abc->name,"Microsoft");
abc->class = "MD5";
abc->rollno = "12345";
printf("%s %s %s\n",abc->name,abc->class,abc->rollno);
return abc;
}
int main(){
test *digest_abc = NULL;
test *abc = NULL;
abc = sample_function();
digest_abc = abc;
printf(" %s %s %s \n",digest_abc->name,digest_abc->class,digest_abc->rollno);
return 1;
}
Pointer has always been a nightmare for me, I never understood it.

test * sample_function ()
{
test *abc;
strcpy(abc->name,"Surya");
What do you think abc points to, here? The answer is, it doesn't really point to anything. You need to initialize it to something, which in this case means allocating some memory.
So, let's fix that first issue:
test * sample_function ()
{
test *abc = malloc(sizeof(*abc));
strcpy(abc->name,"Surya");
Now, abc points to something, and we can store stuff in there!
But ... abc->name is a pointer too, and what do you think that points to? Again, it doesn't really point to anything, and you certainly can't assume it points somewhere you can store your string.
So, let's fix your second issue:
test * sample_function ()
{
test *abc = malloc(sizeof(*abc));
abc->name = strdup("Surya");
/* ... the rest is ok ... */
return abc;
}
Now, there's one last issue: you never release the memory you just allocated (this probably isn't an issue here, but it'd be a bug in a full-sized program).
So, at the end of main, you should have something like
free(abc->name);
free(abc);
return 1;
}
The final issue is a design one: you have three pointers in your structure, and only convention to help you remember which is dynamically allocated (and must be freed) and which point to string literals (and must not be freed).
That's fine, so long as this convention is followed everywhere. As soon as you dynamically allocate class or rollno, you have a memory leak. As soon as you point name at a string literal, you'll have a crash and/or heap damage.
As japreiss points out in a comment, a good way to enforce your convention is to write dedicated functions, like:
void initialize_test(test *obj, const char *name, char *class, char *rollno) {
obj->name = strdup(name);
...
}
void destroy_test(test *obj) {
free(obj->name);
}
test *malloc_test(const char *name, ...) {
test *obj = malloc(sizeof(*obj));
initialize_test(obj, name, ...);
return test;
}
void free_test(test *obj) {
destroy_test(obj);
free(obj);
}

In your function sample_function you return a pointer to abc. You cannot do this in C due to the way Activation Records are organized.
An Activation Record is a data structure that contains all the relevant information for a function call, parameters, return address, addresses of local variables, etc...
When you call a function a new Activation Record gets pushed onto the stack it could look something like this.
// Record for some function f(a, b)
| local variable 1 | <- stack pointer (abc in your case)
| local variable 2 |
| old stack pointer | <- base pointer
| return address |
| parameter 1 |
| parameter 2 |
---------------------
| caller activation |
| record |
When you return from a function this same activation record gets popped off of the stack but what happens if you returned the address of a variable that was on the old record ?
// popped record
| local variable 1 | <- address of abc #
| local variable 2 | #
| old stack pointer | # Unallocated memory, any new function
| return address | # call could overwrite this
| parameter 1 | #
| parameter 2 | #
--------------------- <- stack pointer
| caller activation |
| record |
Now you try to use abc and your program correctly crashes because it sees that you are accessing an area of memory that is unallocated.
You also have problems with allocation, but other answers have already covered that.

In sample_function you declare abc as a pointer to a test structure, but you never initialize it. It's just pointing off into the weeds somewhere. Then you try to dereference it to store values - BOOM.
Your program doesn't need any pointers at all; structures can be passed by value in C.
If you do want to keep similar interfaces to what you have now, you're going to have to add some dynamic allocations (malloc/free calls) to make sure your structures are actually allocated and that your pointers actually point to them.

Related

Creating a singly-linked list

I have a function to join two structs to create a linked list.
Here, is the code:
struct point{
int x;
int y;
struct point *next;
};
void printPoints(struct point *);
void printPoint(struct point *);
struct point * append(struct point *, struct point *);
void main(){
struct point pt1={1,-1,NULL};
struct point pt2={2,-2,NULL};
struct point pt3={3,-3,NULL};
struct point *start, *end;
start=end=&pt1;
end=append(end,&pt2);
end=append(end,&pt3);
printPoints(start);
}
void printPoint(struct point *ptr){
printf("(%d, %d)\n", ptr->x, ptr->y);
}
struct point * append(struct point *end, struct point *newpt){
end->next=newpt;
return newpt;
}
void printPoints(struct point *start){
while(start!=NULL){
printPoint(start);
start=start->next;
}
}
Here, the append function's task involves changing the end pointer.
Both the arguments of append function are pointers; in 1st case, 1st argument is &pt1 and 2nd argument is &pt2.
The function makes a copy of the end pointer which has the type struct point.
Since &pt1 is passed then this duplicate end pointer has x component as 1 and y component as -1 and next component as NULL.
Now we change this copy's next component to newpt pointer and return the newpt pointer.
Back to the main function, the original end pointer now has the value of &pt2.
end->next = newpt; shouldn't produce any change in the original end pointer in main because only the local pointer was changed.
So then why do I get a linked list.
What I get:
(1, -1)
(2, -2)
(3, -3)
What I think I should get:
(1, -1)
end->next = newpt; shouldn't produce any change in the original end pointer in main. Because, only the local pointer was changed
Not quite correct. It is true that when you call append, a copy of end is made. However, the -> operator dereferences what that pointer points to. You would get the same behavior with (*end).. Since the end in main is the same as the end in append, they both point to the same thing. You could have 100 copies of a pointer, all pointing to the same thing. If you choose one, follow what it points to and change that, then you've changed the same thing that all other 99 pointers point to. Furthermore, you reassign end in main by returning newpt, so each call to append results in an updated end. The output you observe is correct. Consider the condensed stack frames:
In main, at first call to append:
____main____
|___pt1____| <----+ <-+
|x=1 y=-1 | | |
|_next=NULL| | |
|___pt2____| | |
|___pt3____| | |
|__start___|------+ |
|___end____|-----------+ // cell sizes NOT drawn to scale
// start and end both point to pt1
Now, on the first call to append, the main stack frame stays the same, and a new one is created for append, where end and the address to pt2 are passed in.
|___main____
|___pt1____| <----+ <-+
|_next=NULL| | | // x and y omitted for brevity
|___pt2____| | |
|___pt3____| | |
|___end____|------+ |
|
___append__ |
|___&pt2___| |
|___end____|-----------+ // also points to pt1 back in main
When you use the -> operator, you dereference what that pointer points to. In this case, pt1, so both end in main and end in append point to pt1. In append, you do
end->next = newpt;
which is the address of pt2. So now your stack frames look like this:
|___main____
|___pt1____| <-----------+ <-+
|_next=&pt2|------+ | | // x and y omitted for brevity
| | | | | // (made pt1 cell bigger just to make the picture clearer, no other reason)
|__________| | | |
|___pt2____| <----+ | |
|___pt3____| | |
|___end____|-------------+ |
|
___append__ |
|___&pt2___| |
|___end____|------------------+ // also points to pt1 back in main
Finally, when you return from append, you return the address of pt2 and assign it to end, so your stack in main looks like this before the 2nd call to append (again, some cells made larger for picture clarity, this does not suggest anything grew in size):
____main____
|___pt1____| <-----------+
|_next=&pt2|---+ |
| | | |
|__________| | |
|___pt2____| <-+ <-+ |
|___pt3____| | |
|___end____|-------+ |
|___start__|-------------+ // flipped start and end position to make diagram cleaner, they don't really change positions on the stack
And you do it all again with your next call to append, passing in end (now points to pt2) and the address of pt3. After all the calls to append, start points to pt1, pt1->next points to pt2, and pt2->next points to pt3, just as you see in the output.
One final note, you have an incorrect function signature for main
As in the illustration start still points to p1 and end points to pt3.
void main(){
struct point pt1={1,-1,NULL};
struct point pt2={2,-2,NULL};
struct point pt3={3,-3,NULL};
struct point *start, *end;
start=end=&pt1;
end=append(end,&pt2);
end=append(end,&pt3);
printPoints(start);
}
As in the main function, you make start and end to point at pt1.
That's why any changes made to end is also seen from start.
struct point * append(struct point *end, struct point *newpt){
end->next=newpt;
return newpt;
}
In the append function, end->next=newpt which sets the next of end to newpt. In the first case, when end points pt1, the next is set to point at pt2. This change in the list is also seen from start.
Hence, the output you are getting is correct.
Changing Pointers
When you pass a pointer to a function, the value of the pointer (that is, the address) is copied into the function not the value it is pointing at.
So, when you dereference the pointer and change it, the change is also seen from any pointer which contain the same address.
Remember that p->next is the same as (*p).next.
void change_the_pointer_reference(int* ip)
{
int i = 1;
*ip = i;
printf("%d\n", *ip); // outputs 1
}
int main()
{
int i = 0;
change_the_pointer_reference(&i);
printf("%d\n", i); // outputs 1
}
But as the value of the pointer is copied, if you assign to the pointer, this change is only seen locally.
void change_the_pointer(int* ip)
{
int i = 1;
ip = &i;
printf("%d\n", *ip); // outputs 1
}
int main()
{
int i = 0;
change_the_pointer(&i);
printf("%d\n", i); // outputs 0
}
Last final note, you have an incorrect signature of main

How is memory allocated to multi-nested structs in C?

A couple of days ago, I asked this question. I duplicated 90% of the code given in the answer to my previous question. However, when I used Valgrind to do memcheck, it told me that there were memory leaks. But I don't think it was that 10% difference that caused the memory leaks. In addition to the memory leak issue, I have a couple of other questions.
A brief summary of my previous post:
I have a multi-nested struct. I need to correctly allocate memory to it and free the memory later on. The structure of the entire struct should look like this:
College Sys
| | | ... |
ColleA ColleB ColleC ... ColleX
| | | | | | | | | | | | ... | | | |
sA sB sC sD sA sB sC sD sA sB sC sD ... sA sB sC sD
| | | | | | | | | | | | ... | | | |
fam fam ...
// Colle is short for college
// s is short for stu (which is short for student)
There could be arbitrary number of colleges and students, which is controllable by #define MAX_NUM _num_.
As per the previous answer, I should allocate memory in the order of "outermost to innermost" and free the memory "innermost to outermost". I basically understand the logic behind the pattern. The following questions are extensions to it.
1) Does
CollegeSys -> Colle = malloc(sizeof(*(CollegeSys -> Colle)) * MAX_NUM);
CollegeSys -> Colle -> stu = malloc(sizeof(*(CollegeSys -> Colle -> stu)) * MAX_NUM);
CollegeSys -> Colle -> stu -> fam = malloc(sizeof(*(CollegeSys -> Colle -> stu -> fam)));
mean " there are MAX_NUM colleges under the college system, each of which has MAX_NUM students — each of which has one family"?
1.a)If yes, do I still need for loops to initialize every single value contained in this huge struct?
For example, the possibly correct way:
for (int i = 0; i < MAX_NUM; i++) {
strcpy(CollegeSys -> Colle[i].name, "collestr");
for (int n = 0; n < MAX_NUM; n++) {
strcpy(system -> Colle[i].stu[n].name, "stustr");
...
}
}
the possibly incorrect way:
strcpy(CollegeSys -> Colle -> name, "collestr");
strcpy(CollegeSys -> Colle -> stu -> name, "stustr");
I tried the "possibly incorrect way". There was no syntax error, but it would only initialize CollegeSys -> Colle[0].name and ... -> stu[0].name. So, the second approach is very likely to be incorrect if I want to initialize every single attribute.
2) If I modularize this whole process, separating the process into several functions that return corresponding struct pointers — newSystem(void), newCollege(void), newStudent(void) (arguments might not necessarily be void; we might also pass a str as the name to the functions; besides, there might be a series of addStu(), etc... to assign those returned pointers to the corresponding part of CollegeSys). When I create a new CollegeSys in newSystem(), is it correct to malloc memory to every nested struct once and for all within newSystem()?
2.a) If I allocate memory to all parts of the struct in newSystem(), the possible consequence I can think of so far is there would be memory leaks. Since we've allocated memory to all parts when creating the system, we inevitably have to create a new struct pointer and allocate adequate memory to it in the other two functions too. For instance,
struct Student* newStudent(void) {
struct Student* newStu = malloc(sizeof(struct Student));
newStu -> fam = malloc(sizeof(*(newStu -> fam)));
// I'm not sure if I'm supposed to also allocate memoty to fam struct
...
return newStu;
}
If so, we actually allocate the same amount of memory to an instance at least twice — one in the newSystem(void), the other in newStudent(void). If I'm correct so far, this is definitely memory leak. And the memory we allocate to the pointer newStu in newStudent(void) can never be freed (I think so). Then, what is the correct way to allocate memory to the whole structure when we separate the whole memory allocation process into several small steps?
3) Do we have to use sizeof(*(layer1 -> layer2 -> ...)) when malloc'ing memory to a struct nested in a struct? Can we directly specify the type of it? For example, doing this
CollegeSys -> Colle = malloc(sizeof(struct College) * MAX_NUM);
// instead of
// CollegeSys -> Colle = malloc(sizeof(*(CollegeSys -> Colle)) * MAX_NUM);
4) It seems even if we allocate a certain amount of memory to a pointer, we still can't prevent segfault. For example, we code
// this is not completely correct C code, just to show what I mean
struct* ptr = malloc(sizeof(struct type) * 3);
We still could call ptr[3], ptr[4] and so on, and the compiler will print out nonsense. Sometimes, the compiler may throw an error but sometimes may not. So, essentially, we can't rely on malloc (or calloc and so forth) to avoid the appearance of segfault?
I'm sorry about writing such a long text. Thanks for your patience.

can pointers exist outside their scope

why does the pointer "a" points to the correct location when i call the function for the second time
because during the second function call to "cr" the statements in the if block will not be executed so how the hell does the pointer "a" remember its previous location even though its not a static variable
code:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
typedef struct heavy{
int data;
struct heavy *nxt;
}ode;
void cr(ode**);
void prin(ode*);
int main()
{
ode*head=NULL;
cr(&head);cr(&head);
prin(head);
getch();
return 0;
}
void cr(ode**p)
{
ode*temp,*a;
temp=*p;
if(temp==NULL)
{
a=(ode*)malloc(sizeof(ode));
a->data=1;
a->nxt=(ode*)malloc(sizeof(ode));
*p=a;
a=a->nxt;
a->nxt=NULL;
}else{
a->data=2;
a->nxt=NULL;
}
}
void prin(ode*head)
{
if(head==NULL)
printf("list is empty");
while(head!=NULL)
{
printf("%d",head->data);
head=head->nxt;
}
}
When you don't assign any value to a local variable (in this case we're talking about a) the program will behave in an unpredictable way, thus we say undefined behavior. This means that your program work correctly just by chance, and you should always remember to assign values before using the variables.
In particular, in this case I can guess why it's working every time you run it, and it has to do with how function calls work in C. Let me explain.
When we make a call to a function, a new frame (layer) in the stack (a place in memory where local variables and other "local-ish" things are stored). As you can expect from what I just said, a stack is organized in layers. Let me expose an example.
If in a particular function called George() I declare and use 2 local variables
int George(){
int a;
int b;
a = 5;
return 0;
}
the compiler will know that space for 2 variables is needed, so when I call the function it will reserve space for those 2 local variables to be stored. The new stack frame will be something like:
| 'a': ____ | <-- 4 bytes space for variable a
| 'b': ____ | <-- 4 bytes space for variable b
|-----------|
(While keeping in mind that this is not a realistic representation of the stack, it's good enough to explain what's going on)
Those spaces reserved for the values of the variables are NOT set to a default value, they contain what there was in memory before (and right now we can't make any guess).
When I call this function from another function (i.e. main) a stack frame with that shape will be added (push) to the stack:
int main(){
int hello = 7;
int hey;
hey = George(); // Here we make the function call
return 0;
}
The stack will then be something like:
STACK:
| 'a': ____ | <- 'George' stack frame, containing
| 'b': ____ | local variables of George
|--------------|
| 'hello': 7 | <- 'main' stack frame, containing
| 'hey': ____ | local variables of main
|--------------|
After the 3rd line of George, just before the return, the stack will be:
STACK:
| 'a': 5 | <- Variable a has been set to 5
| 'b': ____ |
|--------------|
| 'hello': 7 |
| 'hey': ____ |
|--------------|
and then there will be a return. Here, the stack is pop'd, which means a frame is deleted (we are returning in the main function "domain", so we discard local variables of George).
STACK:
| 'hello': 7 | <- 'main' stack frame, with hey replaced with
| 'hey': 0 | George return value (0)
|--------------|
And everything works fine, BUT the memory we pop'd just right now is not set to 0 or some other default value. It stays like that until some other program overrides it. Which means that, while we are not using those values anymore, they're probably still there.
In this state, if we call George another time, we will have our stack pushed another time:
STACK:
| 'a': ____ | <- 'a' address is in the same position
| 'b': ____ | where there was the 'a' in the previous
|--------------| function call to Giorgio
| 'hello': 7 |
| 'hey': ____ |
|--------------|
In this state, if we don't assign any value to a it will (probably) contain the value that the a had on the previous function call, because the 'new' a has the same address of the 'previous' a, because the function called is the same and there was no other function call in between that could override the previous value. If we do so, before we assign any value to the new local variable a, it contains 5.
The same happens to your program when you run
cr(&head);
cr(&head);
twice, one before the other. The value of your local variable a is probably kept unchanged.
Anyway, explanation apart, NEVER use this kind of behaviors in your code. This is a very very bad way of programming, and the outcome is usually unpredictable.
I hope my explanation was not too bad.

I need to make a global array in C with a size inputted by the user

Basically I need to make a global variable in C that is an array. The Array will be [n][22][n+1] where n is either 3,4,5 or 6 and is selected by the user.
Is there a way to do this or should I just make the array [6][22][7], and have the functions dealing with it only use the parts up to n (if that makes any sense)?
I've had to do this before for a computer science class but can't remember exactly how to do it.
For an array that small (well, assuming reasonably sized data types), you might just be better off making the [6][22][7] allocation you mention in your question - it's not like you're going to waste that much space. Unfortunately for you, C99 variable length arrays don't work for global arrays. That means your only other option is dynamic allocation using malloc()/free().
You can use a file scope pointer that points to the first element of an array you dynamically allocate (malloc function) in a function.
As was mentioned previously, in this particular case, doing anything else than a static assignment of [6][22][7] would be a waste of time. If you really want to dynamically allocate the array using malloc :
/* Suppose that you want a [5][22][6] */
int main() {
int i,j,k;
int ***boo;
int d_1,d_2,d_3;
d_1=5;
d_2=22;
d_3=6;
/*
+------------------------------------------+
| For each dimension, a malloc is needed |
+------------------------------------------+
*/
boo = malloc(d_1*sizeof(int*));
for (i=0;i<d_1;i++) {
boo[i] = malloc(d_2*sizeof(int*));
for (j=0;j<d_2;j++) {
boo[i][j] = malloc(d_3*sizeof(int*));
for (k=0;k<d_3;k++) {
boo[i][j][k] = i+j*k;
}
}
}
/*
+----------------------+
| Testing the values |
+----------------------+
*/
for (i=0;i<d_1;i++) {
for (j=0;j<d_2;j++) {
for (k=0;k<d_3;k++) {
printf("%d ",boo[i][j][k]);
}
printf("\n");
}
}
return 0;
}
This would essentially do the trick. It might be useful, if you have a greater amount of data.
Don't forget to deallocate the memory using free()

Confused about accessing struct members via a pointer

I'm new to C, and am confused by results I'm getting when referencing a member of a struct via a pointer. See the following code for an example. What's happening when I reference tst->number the first time? What fundamental thing am I missing here?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int number;
} Test;
Test* Test_New(Test t,int number) {
t.number = number;
return &t;
}
int main(int argc, char** argv) {
Test test;
Test *tst = Test_New(test,10);
printf("Test.number = %d\n",tst->number);
printf("Test.number = %d\n",tst->number);
printf("Test.number = %d\n",tst->number);
}
The output is:
Test.number = 10
Test.number = 4206602
Test.number = 4206602
When you pass test into your Test_New function, you are passing it by value and so a local copy is made on the stack for the function scope of your Test_New function. Since you return the address of the variable, once the function returns the stack is useless but you've returned a pointer to a struct on the old stack! So you can see that your first call returns the correct value since nothing has overwritten your stack value but the subsequent calls (which all use the stack) overwrite your value and give you erroneous results.
To do this correctly rewrite your Test_New function to take a pointer and pass the pointer to the struct into the function.
Test* Test_New(Test * t,int number) {
t->number = number;
return t;
}
int main(int argc, char ** argv) {
Test test;
Test * tst = Test_New(&test,10);
printf("Test.number = %d\n",tst->number);
printf("Test.number = %d\n",tst->number);
printf("Test.number = %d\n",tst->number);
}
Independent of struct, it is always incorrect to return the address of a local variable. It is usually also incorrect to put the address of a local variable into a global variable or to store it in an object allocated on the heap with malloc. Generally if you need to return a pointer to an object, you'll need either to get someone else to provide the pointer for you, or else you'll need to allocate space with malloc, which will return a pointer. In that case, part of the API for your function must specify who is responsible for calling free when the object is no longer needed.
You are returning the address of t as declared in the method Test_New, not the address of test that you passed into the method. That is, test is being passed by value and you should instead pass a pointer to it.
So, here is what happens when you call Test_New. A new Test struct named t is created and t.number is set to be equal to the value of test.number (which you had not initialized). Then you set t.number equal to the parameter number that you passed to the method, and then you return the address of t. But t is a local variable and goes out of scope as soon as the method ends. Thus, you are returning a pointer to data that no longer exists and that is why you are ending up with garbage.
Change the declaration of Test_New to
Test* Test_New(Test* t,int number) {
t->number = number;
return t;
}
and call it via
Test *tst = Test_New(&test,10);
and all will go as you are expecting.
Just to extend BlodBath's answer, think about what happens in memory when you do this.
As you enter your main routine, a new automatic Test struct is created -- on the stack, since it's auto. So your stack looks something like
| return address for main | will be used at bottom
| argc | copied onto stack from environment
| argv address | copied onto stack from environment
-> | test.number | created by definition Test test;
with -> indicating the stack pointer to the last used element of the stack.
Now you call Test_new(), and it updates the stack like this:
| return address for main | will be used at bottom
| argc | copied onto stack from environment
| argv address | copied onto stack from environment
| test.number | created by definition Test test;
| return addr for Test_new| used to return at bottom
| copy of test.number | copied into the stack because C ALWAYS uses call by value
-> | 10 | copied onto stack
When you return &t, which address are you getting? Answer: the address of the data ON THE STACK. BUT THEN you return, the stack pointer is decremented. When you call printf, those words on the stack are re-used, but your address is still poiting to them. It happens that what the number in that location in the stack, interpreted as an address, points to has the value 4206602, but that's pure chance; in fact, it was kind of bad luck, as good luck would have been something that caused a segmentation fault, letting you know something was actually broken.
The problem is that you are not passing a reference into Test_New, you are passing a value. Then, you're returning the memory location of the local variable. Consider this code which demonstrates your problem:
#include <stdio.h>
typedef struct {
} Test;
void print_pass_by_value_memory(Test t) {
printf("%p\n", &t);
}
int main(int argc, char** argv) {
Test test;
printf("%p\n", &test);
print_pass_by_value_memory(test);
return 0;
}
The output of this program on my machine is:
0xbfffe970
0xbfffe950
Test t declared in Test_New() is a local variable. You are trying to return the address of a local variable. As the local variable gets destroyed once the function exists, the memory will be freed meaning, the compiler is free to put some other value in the location where your local variable was kept.
In your program when you are trying to access the value the second time, the memory location might have got assigned to a different variable or process. Hence you are getting the wrong output.
A better option for you will be to pass the structure from main() by reference rather than by value.
You've passed the contents of test by value to Test_New. IOW a new copy of a Test structure has been allocated on the stack when you called Test_New. It is the address of this Test that you return from the function.
When you use tst->number the first time the value of 10 is retrieved because although that stack has be unwound no other use of that memory has been made. However as soon as that first printf has been called the stack memory is reused for whatever it needs, but tst is still pointing to that memory. Hence subsquent uses of tst->number retrieve whatever printf left there in that memory.
Use Test &t in the function signature instead.
You could do something like this to make it a little easier:
typedef struct test {
int number;
} test_t;
test_t * Test_New(int num)
{
struct test *ptr;
ptr = (void *) malloc(sizeof(struct test));
if (! ptr) {
printf("Out of memory!\n");
return (void *) NULL;
}
ptr->number = num;
return ptr;
}
void cleanup(test_t *ptr)
{
if (ptr)
free(ptr);
}
....
int main(void)
{
test_t *test, *test1, *test2;
test = Test_New(10);
test1 = Test_New(20);
test2 = Test_new(30);
printf(
"Test (number) = %d\n"
"Test1 (number) = %d\n"
"Test2 (number) = %d\n",
test->number, test1->number, test2->number);
....
cleanup(test1);
cleanup(test2);
cleanup(test3);
return 0;
}
... As you can see, its easy to allocate room for several completely different instances of test_t, for instance if you need to save the existing state of one so you can revert later .. or for whatever reason.
Unless, of course there is some reason why you must keep it local .. but I really can't think of one.

Resources