tricky question

O

onkar

Program 1:

#include<stdio.h>
int main(void){
int *p;
p=(int *)malloc(sizeof(int));
*p=12;
printf("%d %p\n",*p,p);
return 0;
}

I run the program to get the following output :

12 0x80495b8

now

Program 2:

#include<stdio.h>
int main(void){
int *p;
p=0x80495b8;
printf("%d\n",*p);
return 0;
}

what should be the answer "if ,somehow the Process executing the
program 2 is allowed to access all the memory locations of Process
executing on behalf of Program 1 ".

I think it should be 12 ? correct me if I am wrong //

Thank you,
Onkar
 
S

Stephen Sprunk

onkar said:
Program 1:

#include<stdio.h>
int main(void){
int *p;
p=(int *)malloc(sizeof(int));
*p=12;
printf("%d %p\n",*p,p);
return 0;
}

I run the program to get the following output :

12 0x80495b8

now

Program 2:

#include<stdio.h>
int main(void){
int *p;
p=0x80495b8;
printf("%d\n",*p);
return 0;
}

what should be the answer "if ,somehow the Process executing the
program 2 is allowed to access all the memory locations of Process
executing on behalf of Program 1 ".

I think it should be 12 ? correct me if I am wrong //

It's undefined behavior. On some implementations it may work as you expect,
but on the majority of modern systems the result will be either random,
zero, or a crash (e.g. segfault).

S
 
S

santosh

onkar said:
Program 1:

#include<stdio.h>

Where's stdlib.h for malloc. You're invoking undefined behaviour
already.
int main(void){
int *p;
p=(int *)malloc(sizeof(int));

No need to cast the return value of malloc.
*p=12;
printf("%d %p\n",*p,p);

It's better form to cast the argument corresponding to the %p
specifier to type void pointer.
return 0;
}

I run the program to get the following output :

12 0x80495b8

now

Program 2:

#include<stdio.h>
int main(void){
int *p;
p=0x80495b8;

Implementation defined behaviour.
printf("%d\n",*p);
return 0;
}

what should be the answer "if ,somehow the Process executing the
program 2 is allowed to access all the memory locations of Process
executing on behalf of Program 1 ".

I think it should be 12 ? correct me if I am wrong //

Well, you think wrong. Nothing about the second program is guaranteed.
It invokes undefined behaviour.

<OT>
In typical modern operating systems, each process is given it's own
address space, so the address 0x80495b8 of process two need not
correspond with the same address of process one. In fact, they won't
map to the same physical memory. If they did, then either the
operating system is broken or the system doesn't support virtual
memory, (or virtual memory has been disabled).
</OT>
 
K

Keith Thompson

santosh said:
onkar wrote: [...]
Program 2:

#include<stdio.h>
int main(void){
int *p;
p=0x80495b8;

Implementation defined behaviour.

No, it's a constraint violation.

There is no implicit conversion from integers to pointers (other than
the special case of a null pointer constant). (Some compilers may
allow the assignment as an extension, and will *probably* implement an
implicit conversion, but the standard allows other possibilities.)

If the assignment were changed from
p=0x80495b8;
to
p=(int*)0x80495b8;
then the behavior of the conversion would be implementation-defined.
 
G

Gordon Burditt

Program 1:
#include<stdio.h>
int main(void){
int *p;
p=(int *)malloc(sizeof(int));
*p=12;
printf("%d %p\n",*p,p);
return 0;
}

I run the program to get the following output :

12 0x80495b8

now

Program 2:

#include<stdio.h>
int main(void){
int *p;
p=0x80495b8;
printf("%d\n",*p);
return 0;
}

what should be the answer "if ,somehow the Process executing the
program 2 is allowed to access all the memory locations of Process
executing on behalf of Program 1 ".

If, somehow, the process executing program 2 is allowed to access
all the memory locations of the process executing on behalf of
program 1, it still doesn't mean that the same byte has the same
address in both programs, even if somehow you get the two programs
running at the same time.

You can get a limited version of this with mmap() available on some
systems. You don't have to map the same segment to the same address
in two different processes.
I think it should be 12 ? correct me if I am wrong //

You get no guarantees.
 
B

Barry Schwarz

Where's stdlib.h for malloc. You're invoking undefined behaviour
already.


No need to cast the return value of malloc.


It's better form to cast the argument corresponding to the %p
specifier to type void pointer.

Actually, it's mandatory.



Remove del for email
 
K

Keith Thompson

Barry Schwarz said:
Actually, it's mandatory.

It's mandatory in the sense that failing to do so (unless the pointer
is already of type void* or of a pointer-to-character type) invokes
undefined behavior. But the compiler is under no obligation to tell
you about the error, and on many systems the call without the cast
happens to behave exactly like the proper call with the cast.
 
B

Barry Schwarz

Program 1:

#include<stdio.h>
int main(void){
int *p;
p=(int *)malloc(sizeof(int));

This cast prevented the compiler from informing you that you have done
something illegal. Your program invokes undefined behavior.
*p=12;
printf("%d %p\n",*p,p);

There is a mismatch between the %p and the type of the corresponding
argument. More undefined behavior.
return 0;
}

I run the program to get the following output :

12 0x80495b8

now

Program 2:

#include<stdio.h>
int main(void){
int *p;
p=0x80495b8;

Did not your compiler issue a diagnostic for this statement? Why did
you ignore it?
printf("%d\n",*p);

More undefined behavior.

First, you have no idea if 0x80495b8 is within the address
space of your program. Based on your first set of code, I would bet
that it is not..

Second, even if it is, you never initialized it with a value.
Therefore, the value is indeterminate. You are not allowed to
evaluate indeterminate values.
return 0;
}

what should be the answer "if ,somehow the Process executing the
program 2 is allowed to access all the memory locations of Process
executing on behalf of Program 1 ".

For undefined behavior, the answer should always be household voltage
applied to the seat of the programmers chair.

Even if your if could be true, most user systems today use virtual
memory and two processes referring to the same logical address
actually refer to different physical addresses.
I think it should be 12 ? correct me if I am wrong //

Undefined behavior is always wrong.


Remove del for email
 
N

Nick Keighley

onkar said:
Program 1:

#include<stdio.h>
int main(void){
int *p;
p=(int *)malloc(sizeof(int));
*p=12;
printf("%d %p\n",*p,p);
return 0;
}

I run the program to get the following output :

12 0x80495b8

now

Program 2:

#include<stdio.h>
int main(void){
int *p;
p=0x80495b8;
printf("%d\n",*p);
return 0;
}

what should be the answer "if ,somehow the Process executing the
program 2 is allowed to access all the memory locations of Process
executing on behalf of Program 1 ".

I think it should be 12 ? correct me if I am wrong //

besides the undefined behaviour of assigning an int to an int*
you also forgot to initialise *p to 12. There's no *way* the
printf() could print 12

(ok, it's 1 chance in sizeof(int))


--
Nick Keighley

"If, indeed the subatomic energy in the stars is being freely
used to maintain their great furnaces, it seems to bring a little
nearer to fulfillment our dreams of controlling this latent
power for the well-being of the human race - or for its suicide."
Aurthur S. Eddington "The Internal Constitution of the Stars" 1926
 
K

Keith Thompson

Nick Keighley said:
besides the undefined behaviour of assigning an int to an int*
you also forgot to initialise *p to 12. There's no *way* the
printf() could print 12

I think the idea was that Program 2 would run immediately after
Program 1, and would occupy the same memory space. In reality, that's
unlikely.
(ok, it's 1 chance in sizeof(int))

I think you mean something like one chance in UINT_MAX+1.
 
D

Dave Vandervies

I think you mean something like one chance in UINT_MAX+1.

Not quite that, either.

There is a nonzero chance that the program won't be allowed to access
the memory that p is pointing at.

There's also a good chance that the bit pattern it's pointing at won't
have a uniform probability distribution; for example, many OSs zero-fill
memory before giving it to a program, and if the memory has been used
already in the program's run (f'rexample, by loading shared libraries
or initializing the runtime library) then the values left behind by that
use will probably follow fairly predictable patterns.

Given that the pointer can be dereferenced without causing a crash
and that the bit pattern follows a uniform probability distribution,
the probability that the value it points at will be 12 is (number of
representations of the value 12 for type int) chances in (two the power
of CHAR_BIT*sizeof(int)).

If there are no padding bits in int (so exactly one possible bit
pattern represents the value 12) or in unsigned int (so UINT_MAX+1 is
the number of possible bit patterns), then given accessibility of memory
and uniformly distributed patterns the likelihood of getting a 12 does
reduce to one chance in UINT_MAX+1, but it's not hard to construct a
case where it won't.


dave
 
A

Al Balmer

On Thu, 8 Mar 2007 18:52:54 +0000 (UTC),
If there are no padding bits in int (so exactly one possible bit
pattern represents the value 12) or in unsigned int (so UINT_MAX+1 is
the number of possible bit patterns), then given accessibility of memory
and uniformly distributed patterns the likelihood of getting a 12 does
reduce to one chance in UINT_MAX+1, but it's not hard to construct a
case where it won't.

I used to tell our programmers that a chance in a million means the
computer will do it once a second. That was back when computers were
slow :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top