The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> C Programming
|
[ANSI C,Unix/Win]Struct passing
Discuss [ANSI C,Unix/Win]Struct passing in the C Programming forum on Dev Shed. [ANSI C,Unix/Win]Struct passing C programming forum discussing all C derivatives, including C#, C++, Object-C, and even plain old vanilla C. These languages are low level languages, and used on projects such as device drivers, compilers, and even whole computer operating systems.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

November 15th, 2009, 07:38 PM
|
|
Registered User
|
|
Join Date: Oct 2009
Posts: 53
Time spent in forums: 7 h 26 m 22 sec
Reputation Power: 0
|
|
|
[ANSI C,Unix/Win]Struct passing
I wrote this code seeing K&R. I have two confusions.
1) Even though we are returning a local variable from the function then also we see that it is not destroyed and is returned correctly.
2) While returning from the function cs() the copy to the structure ptr is made automatically. In c++ we use copy constructor to do it but i think this is c so little confused how it is done.
Code:
#include<stdio.h>
struct point
{
int x;
int y;
};
struct point cs(int i,int j)
{
struct point p;
p.x=i;
p.y=j;
return p;
}
main()
{
struct point ptr;
ptr=cs(5,7);
printf("the struct x is %d",ptr.x);
printf("the struct y is %d",ptr.y);
}
|

November 15th, 2009, 08:13 PM
|
 |
Still alive
|
|
Join Date: Mar 2007
Location: Washington, USA
|
|
It isn't "returning a local variable from a function" - it is returning a copy.
C does a lot of stuff by making copies. In main, with cs(5, 7), the two numbers are somewhere in memory. When it calls cs it makes a copy of those two numbers and set i=copy of 5 and j=copy of 7.
When cs returns C automatically makes a copy of whatever is being returned. structs are simple so C can make a copy of it, however the copy only goes over the immediate values inside - no deeper.
c Code:
Original
- c Code |
|
|
|
#include <stdio.h> struct example { int x; int y; int* z; // a pointer to a number }; struct example cs(int i, int j) { struct example e1; int k; // set some values e1.x = i; e1.y = j; k = i * j; e1.z = &k; // k will be destroyed at the end of this function printf("cs: address of e1 is 0x%X\n", &e1 ); printf("e1.z = 0x%X\n", e1. z); printf("*e1.z = %d\n", * (e1. z)); return e1; // return a "shallow copy" of e1 } int main() { struct example e2; e2 = cs(5, 7); // e2 is a "shallow copy" of cs's e1 printf("main: address of e2 is 0x%X\n", &e2 ); // different memory address printf("e2.x = %d\n", e2. x); // same value printf("e2.y = %d\n", e2. y); // same value printf("e2.z = 0x%X\n", e2. z); // same value printf("*e2.z = %d\n", * (e2. z)); // k was destroyed so the memory was reused for something else return 0; }
|

November 15th, 2009, 08:20 PM
|
|
|
Quote: | While returning from the function cs() the copy to the structure ptr is made automatically. |
Try:
Code:
struct point
{
int x;
int y;
};
void cs(int i, int j, struct point *p)
{
p->x = 5;
p->y = 6;
}
int _tmain(int argc, _TCHAR* argv[])
{
struct point t;
cs(5,6,&t);
printf("X: %d",t.x);
printf("Y: %d",t.y);
return 0;
}
What the above code is doing is assigning 16 bytes of memory to t (int = 8 bytes, 2x int = 16 bytes). When you call cs, you are passing the address (&t) of those 16 bytes to the variable p (*p) which is of type struct.
It is important to note that no new memory is created for the structure in the cs call; the * by p tells the compiler to dereference the data stored in p (passed to it by when we made the call to cs and passed the address of t), causing it to access the data in memory t directly. This assignment uses 2 bytes of memory, and not 18 as we are not creating a second, temporary copy of the structure in memory.
The function type is void as it does not need to return anything - it wrote directly to the memory at t, so when we return, we already have the data in the structure.
The difference between '->' and '.' is this:
In the main() function it is t .x because it is referencing member x in t which is of type structure ( struct point t).
In the cs function, it is p ->x because p is a pointer to the member x in structure t ( struct point *p in the cs function declaration), and is not a structure itself.
Best regards,
AstroTux.
Last edited by AstroTux : November 15th, 2009 at 09:19 PM.
|

November 16th, 2009, 04:41 PM
|
|
Registered User
|
|
Join Date: Oct 2009
Posts: 53
Time spent in forums: 7 h 26 m 22 sec
Reputation Power: 0
|
|
Just to make things more clear the reason the pointer z did not had the real value because it was allocated on the stack which needs to be freed once the function returns.So in requinix code we were able to get back the address of the pointer correctly but since the pointer was freed so the value was not correct.
In case it would have been on heap then this problem would not have been there . Please look at the code below
Code:
#include<stdio.h>
struct point
{
int x;
int y;
char *z;
};
struct point cs(int i,int j)
{
struct point p;
char *zr;
zr=(char *)malloc(30);
if(zr==NULL)
printf("not able to allocate the memory");
zr="weareone";
p.x=i;
p.y=j;
p.z=zr;
return p;
}
main()
{
struct point ptr;
ptr=cs(5,7);
printf("the struct x is %d",ptr.x);
printf("the struct y is %d",ptr.y);
printf("the struct y is %s",ptr.z);
}
Quote: | Originally Posted by requinix It isn't "returning a local variable from a function" - it is returning a copy.
C does a lot of stuff by making copies. In main, with cs(5, 7), the two numbers are somewhere in memory. When it calls cs it makes a copy of those two numbers and set i=copy of 5 and j=copy of 7.
When cs returns C automatically makes a copy of whatever is being returned. structs are simple so C can make a copy of it, however the copy only goes over the immediate values inside - no deeper.
c Code:
Original
- c Code |
|
|
|
#include <stdio.h> struct example { int x; int y; int* z; // a pointer to a number }; struct example cs(int i, int j) { struct example e1; int k; // set some values e1.x = i; e1.y = j; k = i * j; e1.z = &k; // k will be destroyed at the end of this function printf("cs: address of e1 is 0x%X\n", &e1 ); printf("e1.z = 0x%X\n", e1. z); printf("*e1.z = %d\n", * (e1. z)); return e1; // return a "shallow copy" of e1 } int main() { struct example e2; e2 = cs(5, 7); // e2 is a "shallow copy" of cs's e1 printf("main: address of e2 is 0x%X\n", &e2 ); // different memory address printf("e2.x = %d\n", e2. x); // same value printf("e2.y = %d\n", e2. y); // same value printf("e2.z = 0x%X\n", e2. z); // same value printf("*e2.z = %d\n", * (e2. z)); // k was destroyed so the memory was reused for something else return 0; }
|
|

November 16th, 2009, 10:59 PM
|
|
Contributing User
|
|
Join Date: Sep 2008
Posts: 55
Time spent in forums: 11 h 51 m 5 sec
Reputation Power: 0
|
|
|
Reply
function only return value,not object.
Local variable or object will destruct after leave function.
in your code,ret will be a uncertain pointer.
|

November 17th, 2009, 11:31 AM
|
 |
Bellevue WA, USA
|
|
Join Date: May 2004
Location: Bellevue Washington, USA
|
|
Quote: | Originally Posted by dspgro Please look at the code below |
Why? What are we looking for?
The memory leak? You allocate 30 bytes with malloc and assign the pointer to that memory to zr, then you overwrite zr when you point it to the string literal "wearone". C will not copy strings for you using the the assignment operator. All that does is change the value of the pointer itself. You'll need to use strcpy() if you want "wearone" to wind up in the buffer you allocated on the heap.
__________________
My worst nightmare was a pointless infinite loop.
Work in progress; don't poke the curmudgeon!
http://www.odonahue.com/
|

November 17th, 2009, 12:54 PM
|
|
Registered User
|
|
Join Date: Oct 2009
Posts: 53
Time spent in forums: 7 h 26 m 22 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by jwdonahue Why? What are we looking for?
The memory leak? You allocate 30 bytes with malloc and assign the pointer to that memory to zr, then you overwrite zr when you point it to the string literal "wearone". C will not copy strings for you using the the assignment operator. All that does is change the value of the pointer itself. You'll need to use strcpy() if you want "wearone" to wind up in the buffer you allocated on the heap. |
thanks for the email. This is indeed a memory leak.
This also means that zr="weareone"; was not allocated on the stack which is little bit confusing since we are able access these outside the function.
Does this means that weareone was allocated somewhere else in some compile area which was not destroyed even though the function call was terminated or completed. ?
|

November 17th, 2009, 01:42 PM
|
 |
Bellevue WA, USA
|
|
Join Date: May 2004
Location: Bellevue Washington, USA
|
|
|
All string literals are allocated in memory somewhere. Where exactly they wind up is up to the compiler writer. A string literal is just a constant array of chars and the language provides implicit conversion to char*.
You should not attempt to write to *zr after assigning it the address of a string literal, as these can and should be stored in read-only memory.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|