LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 05-04-2004, 12:21 PM   #1
ananthbv
Member
 
Registered: Nov 2003
Posts: 49

Rep: Reputation: 15
A main can be changed by a function local without passing anything to the function?


sorry, the question should have been

"a main 'variable' can be changed by a function local without passing anything to the function?"



Hi,
I have this piece of code:

Code:
main()
{
	int i = 5;
	func();
	printf("%d", i);
}

func()
{
	int x;
	int *y = &x;
	x[4] = 20;
}
Surprisingly, this prints 20 and not 5. Someone please tell me what is happening here.

Last edited by ananthbv; 05-04-2004 at 12:24 PM.
 
Old 05-04-2004, 12:37 PM   #2
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
Code:
13:33 aluser@alf:~/C$ cat foo.c
#include <stdio.h>
main()
{
        int i = 5;
        func();
        printf("%d", i);
}

func()
{
        int x;
        int *y = &x;
        x[4] = 20;
}
13:33 aluser@alf:~/C$ gcc -o foo foo.c
foo.c: In function `func':
foo.c:13: error: subscripted value is neither array nor pointer
This is on gcc 3.3.3.

I can't imagine that x[4] would compile, because x is not a pointer or array and, even if the compiler wanted to interpret x as a pointer, what would be the size of its target?

What compiler are you using?
 
Old 05-04-2004, 12:59 PM   #3
ananthbv
Member
 
Registered: Nov 2003
Posts: 49

Original Poster
Rep: Reputation: 15
extremely sorry, that should be y[4], NOT x[4].

I am using the gcc compiler ( i don't know the exact version) on Redhat 7.3.
 
Old 05-04-2004, 01:03 PM   #4
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
You can type gcc --version to get the version.

Using y[4] I get 5 as the output, as expected. Same with gcc 2.95.4.
 
Old 05-04-2004, 01:05 PM   #5
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
still, given that change it's not inconceivable that y[4], since it goes off the end of what effectively is a one element array, ends up writing into a variable in another stack frame on your system. Somebody more familiar with the low level details should confirm.

One thing you could do to check if this is the case is printf("%p\n", &y[4]) in func() and printf("%p\n", &i) in main(), and see if the addresses are the same.
 
Old 05-04-2004, 01:15 PM   #6
ananthbv
Member
 
Registered: Nov 2003
Posts: 49

Original Poster
Rep: Reputation: 15
yeah, i tried printing all possible addresses, like
&i, &x, y, &y[0], &y[1], &y[2], &y[3], &y[4].
the addresses of i and x differed by 16. so the contents of (y + offset of 4) should give the value of i, right? but isn't this dangerous? a function may alter contents of another function and bugs like these are most difficult to find. what can i do to avoid this?
 
Old 05-04-2004, 01:20 PM   #7
infamous41md
Member
 
Registered: Mar 2003
Posts: 804

Rep: Reputation: 30
you're just manually moving up the stack frame into main's territory, like aluser said. here is pic of teh stack when u enter function func:
Code:
[   y             ]  // end main stack frame
[  saved eip  ]  ///begin func() stack frame
[  saved ebp ]
[   x             ]
[    y            ]
so if u count up 4 indices u can see you are invading main's stack frame and changing y. and no u should NOT be doing this.

Last edited by infamous41md; 05-04-2004 at 01:21 PM.
 
Old 05-04-2004, 01:24 PM   #8
ananthbv
Member
 
Registered: Nov 2003
Posts: 49

Original Poster
Rep: Reputation: 15
right, but if i have to do it, i should declare an array of required number of elements and keep myself within the limits, is that it?
 
Old 05-04-2004, 01:24 PM   #9
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
ah ok, then you understand the situation perfectly

This is a reason that not many languages have pointers like C and C++. Through a pointer you can access *any* memory address which is writable (or readable depending on what you're doing) by your process. There's really no magic answer except be careful.

If you're doing a lot of dynamic allocations you can use Electric Fence or dmalloc to help catch errors where you write past the end of an array (they do this by hacking malloc() and friends so that they always return a pointer to memory which is lined up against a non-readable non-writable page, so an overrun will seg fault). dmalloc can help debug memory leaks too.

Java (and a mess of other languages) people like to rub all this in C/C++ people's noses. C/C++ people point out that they want to tell the language what to do, not the other way around.

edit: I wrote this in response to
Quote:
yeah, i tried printing all possible addresses, like
&i, &x, y, &y[0], &y[1], &y[2], &y[3], &y[4].
the addresses of i and x differed by 16. so the contents of (y + offset of 4) should give the value of i, right? but isn't this dangerous? a function may alter contents of another function and bugs like these are most difficult to find. what can i do to avoid this?
but other responses were added in the meantime.

Last edited by aluser; 05-04-2004 at 01:25 PM.
 
Old 05-04-2004, 01:27 PM   #10
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
oh yeah, it's also a reason why other languages have dynamic bounds checking on arrays. C/C++ people point out that this adds a bunch of extra code/bloat, and the program can be made faster by omitting the checks and making sure you don't run off the ends : )
 
Old 05-04-2004, 01:31 PM   #11
ananthbv
Member
 
Registered: Nov 2003
Posts: 49

Original Poster
Rep: Reputation: 15
okkk, thanks a lot, you guys are great!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
passing structures to function b123coder Programming 3 04-20-2005 10:15 AM
Passing Arguments into the Thread Function George_gk Programming 2 01-31-2005 05:03 AM
Passing one php function result as a parameter to another php function davee Programming 13 09-12-2004 12:08 PM
passing a string to a function jkobrien Programming 8 11-05-2003 01:41 PM
help passing char* to function call PTBmilo Programming 4 03-16-2003 07:05 PM


All times are GMT -5. The time now is 05:40 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration