Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

pointers in C difference in gcc under linux

Status
Not open for further replies.

sagar474

Full Member level 5
Joined
Oct 18, 2009
Messages
285
Helped
5
Reputation
10
Reaction score
5
Trophy points
1,318
Location
India,kakinada
Activity points
3,122
I wrote following C program and compiled in turbo C compiler in windows
Code:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
int main()
{
int b,c,d;
int *p;
b=1;
c=2;
d=3;
 
p=&c;
++p;
printf("%d",*p--);
printf("%d",*--p);
return 0;
}
}



when executed the output is...
Code:
>  13
i again compiled in Linux gcc but the out put is.

Code:
-108171742-1081717432

what could be the mater?
 

I don't get what you are doing in your code.
You have three integer variables b,c,d
you assign to integer pointer p the memory location of c
then you increase the pointer location (++p) but at this point I don't think you can't be sure of what is at the new location of your pointer so why do you do that?

and then inside the printf
*p++; assign the value pointed by p, and then increment the address p
*++p; increment the address p, then assign value pointed to by p

I'm not sure how are b,c,d placed in memory but maybe you should declare an array of three integers to be sure that the locations that you point to have the actual data of these three variables.

Alex
 

but it is working in windows
my question is why it is not working on Linux
 

I would be more curious why it works in windows :smile:
I assume that the three integer variables are placed in contiguous memory location but in linux they are not.
You can't rely on that and write your code like you are pointing to an array, if you want an array then declare an array so that the elements are stored in contiguous memory locations.

Alex
 

what creating the difference? the compiler or Linux operating system.

then how the memory is allocating in the Linux?
 

What Alex is telling you is your pointers are not necessarily pointing at anything. When you use pointers to access variables you must have the variable at the address specified in the pointer, by advancing the pointer to the next address you may well be pointing to something else which is completely irrelevant. You would be picking up an almost random value. Remember that pointers are not the variables - they are the addresses where variables are saved in memory.

It may well be that in Windows and on the occasion you ran the program it gave the result you expected. You might run it again and get a completely different result. There is no guarantee where variables will be placed in memory in either operating system so targetting an address beyond where a known variable is doesn't mean another variable will be there instead. There is no need for any opeating system to allocate consecutive addresses to variables, you were just lucky on that occasion, the linker program could just of easily located them somewhere else.

Brian.
 

what creating the difference? the compiler or Linux operating system.

Most likely both, but do in large part to the differences in compilers/linkers, as betwixt pointed out, the results are unpredictable.

If your still curious, have the both compilers generate a ASM listing during compilation. You can really see the differences in the way each compiled program is structured.

Or better yet open the object files with a hex editor.
 
What Alex is telling you is your pointers are not necessarily pointing at anything. When you use pointers to access variables you must have the variable at the address specified in the pointer, by advancing the pointer to the next address you may well be pointing to something else which is completely irrelevant. You would be picking up an almost random value. Remember that pointers are not the variables - they are the addresses where variables are saved in memory.

It may well be that in Windows and on the occasion you ran the program it gave the result you expected. You might run it again and get a completely different result. There is no guarantee where variables will be placed in memory in either operating system so targetting an address beyond where a known variable is doesn't mean another variable will be there instead. There is no need for any opeating system to allocate consecutive addresses to variables, you were just lucky on that occasion, the linker program could just of easily located them somewhere else.

i run the program many times in windows it gives same out put. and i know what actually the pointer is doing.

this is only my experiment.

---------- Post added at 20:05 ---------- Previous post was at 20:01 ----------

Most likely both, but do in large part to the differences in compilers/linkers, as betwixt pointed out, the results are unpredictable.

If your still curious, have the both compilers generate a ASM listing during compilation. You can really see the differences in the way each compiled program is structured.

Or better yet open the object files with a hex editor.

thank you

and how can i see the ASM listing during compilation.
 

Hi sagar474,

GCC:

If you want to see the C code together with the assembly it was converted to, use a command line like this:

gcc -c -g -Wa,-a,-ad [other GCC options] foo.c > foo.lst

Which will output the combined C/assembly listing to the file foo.lst.

Turbo C:

I had to blow the dust of this manual!

tcc –S foo.c

You maybe able to combine both the C and ASM into one file like the GCC example above, but I'd have to read more of the manual to remember.

Also, if you want to hand disassemble you can open the object file with a hex editor and the map files to get even a clearer picture of the inner workings of each compiler.

If you run Turbo C on a DOS platform you can pull all types of tricks, including assigning a pointer to a string literal and then modifying its contents, try that on modern OSs and it will throw a memory partition violation error, as it should.

Hope this helps you in your quest.
 

I observed another surprising thing.

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<stdio.h>
int main()
{
int b,c,d;
int *p;
b=1;
c=2;
d=3;
p=&d;
 
printf("\n address of b is %p ",&b);
printf("\n address of c is %p ",&c);
printf("\n address of d is %p ",&d);
printf("\n \n pointer points to %p it contains %d",p++,*p);
printf("\n pointer points to %p it contains %d",p++,*p);
printf("\n pointer points to %p it contains %d \n",p,*p);
return 0;
 
}



i executed the program several times and i observed the follower out put.
OUT put

Screenshot-2.png


1) the memory is allocating at random each time the program is executing.
2) the memory is allocating in successive memory locations for each variable.

but this is different in previous program. why?

I have don some change to the program and executed again.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<stdio.h>
 
int main()
 
{
 
 
 
int b,c,d;
int *p;
b=1;
c=2;
d=3;
p=&d;
 
 
/*  Now these lines are commented
//printf("\n address of b is %p ",&b);
//printf("\n address of c is %p ",&c);
//printf("\n address of d is %p ",&d);
*/
 
 
 
printf("\n \n pointer points to %p it contains %d",p++,*p);
printf("\n pointer points to %p it contains %d",p++,*p);
printf("\n pointer points to %p it contains %d \n",p,*p);
 
return 0;
}



and observed the out put

Screenshot-3.png
 
Last edited:

You are not understanding the nature of pointers or of the C language or the operating system.

The addresses are not hard coded into the program, they are allocated at run time. If you wanted to use fixed addresses you may as well not use pointers at all but write your own addresses in code. When you execute the program it contains code that requests memory from the operating system. The operating system should in turn allocate a free block of addresses and declare them 'out of bounds' to other programs. The OS decides which addresses are available for use and these will not be the same each time because other applications or OS routines are also requesting their own address blocks as well.

Brian.
 

You are not understanding the nature of pointers or of the C language or the operating system.

The addresses are not hard coded into the program, they are allocated at run time. If you wanted to use fixed addresses you may as well not use pointers at all but write your own addresses in code. When you execute the program it contains code that requests memory from the operating system. The operating system should in turn allocate a free block of addresses and declare them 'out of bounds' to other programs. The OS decides which addresses are available for use and these will not be the same each time because other applications or OS routines are also requesting their own address blocks as well.

Brian.

thanks for your information.
but you are not understanding my question.
I'm examining the program complication process.

these are only my observations
1) the memory is allocating at random each time the program is executing.
2) the memory is allocating in successive memory locations for each variable.

and my question is it is not happening in the second program where i blocked the printf statements. why?
 
Last edited:

these are only my observations
2) the memory is allocating in successive memory locations for each variable.

You can not be sure of that , it may happen and it may not, that it what we are trying to tell you.
Asking why it happens in windows and not in Linux is irrelevant , it may happen in both or none of them , you can't base any code on the assumption that the memory locations will be contiguous.

Alex
 

Also if you are using a multi-tasking operating system such as modern versions of Windows and Linux the addresses you are printing are virtual addresses in the address space of the program. A memory management unit is responsible for mapping virtual addresses into physical addresses at execution time. When using a microcontroller without a memory management unit (such as PIC16s, PIC18s, PIC24s etc) you are using real physical addresss.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top