C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old November 15th, 2009, 07:38 PM
dspgro dspgro is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2009
Posts: 53 dspgro Negative: is most likely a SPAMMER and a traitor to the cause. 
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);


}

Reply With Quote
  #2  
Old November 15th, 2009, 08:13 PM
requinix's Avatar
requinix requinix is offline
Still alive
Dev Shed God 16th Plane (12500 - 12999 posts)
 
Join Date: Mar 2007
Location: Washington, USA
Posts: 12,872 requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)  Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1
Time spent in forums: 5 Months 1 Week 5 Days 6 h 51 m 41 sec
Reputation Power: 8977
Send a message via AIM to requinix Send a message via MSN to requinix Send a message via Yahoo to requinix Send a message via Google Talk to 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
  1. #include <stdio.h>
  2.  
  3. struct example {
  4.     int x;
  5.     int y;
  6.     int* z; // a pointer to a number
  7. };
  8.  
  9. struct example cs(int i, int j) {
  10.     struct example e1;
  11.     int k;
  12.  
  13.     // set some values
  14.     e1.x = i;
  15.     e1.y = j;
  16.     k = i * j; e1.z = &k; // k will be destroyed at the end of this function
  17.  
  18.     printf("cs: address of e1 is 0x%X\n", &e1);
  19.     printf("e1.x = %d\n", e1.x);
  20.     printf("e1.y = %d\n", e1.y);
  21.     printf("e1.z = 0x%X\n", e1.z);
  22.     printf("*e1.z = %d\n", *(e1.z));
  23.  
  24.     return e1; // return a "shallow copy" of e1
  25. }
  26.  
  27. int main() {
  28.     struct example e2;
  29.  
  30.     e2 = cs(5, 7); // e2 is a "shallow copy" of cs's e1
  31.  
  32.     printf("main: address of e2 is 0x%X\n", &e2); // different memory address
  33.     printf("e2.x = %d\n", e2.x); // same value
  34.     printf("e2.y = %d\n", e2.y); // same value
  35.     printf("e2.z = 0x%X\n", e2.z); // same value
  36.     printf("*e2.z = %d\n", *(e2.z)); // k was destroyed so the memory was reused for something else
  37.  
  38.     return 0;
  39. }

Reply With Quote
  #3  
Old November 15th, 2009, 08:20 PM
AstroTux AstroTux is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Feb 2008
Posts: 593 AstroTux User rank is Sergeant Major (2000 - 5000 Reputation Level)AstroTux User rank is Sergeant Major (2000 - 5000 Reputation Level)AstroTux User rank is Sergeant Major (2000 - 5000 Reputation Level)AstroTux User rank is Sergeant Major (2000 - 5000 Reputation Level)AstroTux User rank is Sergeant Major (2000 - 5000 Reputation Level)AstroTux User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 5 Days 21 m 29 sec
Reputation Power: 42
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.

Reply With Quote
  #4  
Old November 16th, 2009, 04:41 PM
dspgro dspgro is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2009
Posts: 53 dspgro Negative: is most likely a SPAMMER and a traitor to the cause. 
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
  1. #include <stdio.h>
  2.  
  3. struct example {
  4.     int x;
  5.     int y;
  6.     int* z; // a pointer to a number
  7. };
  8.  
  9. struct example cs(int i, int j) {
  10.     struct example e1;
  11.     int k;
  12.  
  13.     // set some values
  14.     e1.x = i;
  15.     e1.y = j;
  16.     k = i * j; e1.z = &k; // k will be destroyed at the end of this function
  17.  
  18.     printf("cs: address of e1 is 0x%X\n", &e1);
  19.     printf("e1.x = %d\n", e1.x);
  20.     printf("e1.y = %d\n", e1.y);
  21.     printf("e1.z = 0x%X\n", e1.z);
  22.     printf("*e1.z = %d\n", *(e1.z));
  23.  
  24.     return e1; // return a "shallow copy" of e1
  25. }
  26.  
  27. int main() {
  28.     struct example e2;
  29.  
  30.     e2 = cs(5, 7); // e2 is a "shallow copy" of cs's e1
  31.  
  32.     printf("main: address of e2 is 0x%X\n", &e2); // different memory address
  33.     printf("e2.x = %d\n", e2.x); // same value
  34.     printf("e2.y = %d\n", e2.y); // same value
  35.     printf("e2.z = 0x%X\n", e2.z); // same value
  36.     printf("*e2.z = %d\n", *(e2.z)); // k was destroyed so the memory was reused for something else
  37.  
  38.     return 0;
  39. }

Reply With Quote
  #5  
Old November 16th, 2009, 10:59 PM
tomtforever tomtforever is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 55 tomtforever Negative: is most likely a SPAMMER and a traitor to the cause. 
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.
Comments on this post
AstroTux agrees!

Reply With Quote
  #6  
Old November 17th, 2009, 11:31 AM
jwdonahue's Avatar
jwdonahue jwdonahue is offline
Bellevue WA, USA
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: May 2004
Location: Bellevue Washington, USA
Posts: 3,398 jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level) 
Time spent in forums: 3 Weeks 5 Days 6 h 48 m 17 sec
Reputation Power: 886
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/

Reply With Quote
  #7  
Old November 17th, 2009, 12:54 PM
dspgro dspgro is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2009
Posts: 53 dspgro Negative: is most likely a SPAMMER and a traitor to the cause. 
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. ?

Reply With Quote
  #8  
Old November 17th, 2009, 01:42 PM
jwdonahue's Avatar
jwdonahue jwdonahue is offline
Bellevue WA, USA
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: May 2004
Location: Bellevue Washington, USA
Posts: 3,398 jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level) 
Time spent in forums: 3 Weeks 5 Days 6 h 48 m 17 sec
Reputation Power: 886
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.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > [ANSI C,Unix/Win]Struct passing

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap