Direct Pointer assignment

C

Chen Shusheng

Hello,
I have a small piece of code that I want to directly assign a segment of
memory to a pointer. But complier tell me wrong. Pls you help.Codes below:
 
W

Walter Roberson

Chen Shusheng said:
I have a small piece of code that I want to directly assign a segment of
memory to a pointer. But complier tell me wrong. Pls you help.Codes below:
int * p;
p=0x241ff5c;

The result of converting an integer to a pointer is implementation
defined, so what you are proposing is not portable. If the behaviour
is documented for your implementation, then you can use it in
non-portable code specific to your implementation, according to the
documented functionality. The functionality, when it exists, is not
certain to be linear -- for example, in order to create a pointer
to arbitrary memory location 0x241ff5c, you value you assign might
have to be something like (say) 0x003bff5c8241UL. The standard
basically just says that implementations are allowed to create any
mapping they want, including not allowing any mapping.

In any case, in order to have 0x241ff5c processed *somehow* into
-some- pointer or other, in your example you would use,

int *p;
p = (int *)0x241ff5c;

Or, more simply,

int *p = (int *)0x241ff5c;
 
J

Jack Klein

Hello,
I have a small piece of code that I want to directly assign a segment of
memory to a pointer. But complier tell me wrong. Pls you help.Codes below:

Why? What's at that memory address?

C allows a value of integer type to be assigned to any pointer type,
with a suitable cast:

int *p = (int *)0x2411ff5c;

The result is implementation-defined, and might not have the proper
alignment. The result of actually dereferencing such a pointer is
completely undefined.
 
C

Chen shuSheng

I have two programs. In program 1, I assign a value to that addr. After
running, program 1 is closed. Then I run program2 with this code. All I want
to do is to see if program 1 assign a value to a addr, will it remains there
and can program 2 read that value. That is the purpose. That you all for
help. The result is No. The memory will be released.
 
C

Chen shuSheng

P.S. I am not quit sure about "implementation-defined". Could you pls
explain this?
 
W

Walter Roberson

I have two programs. In program 1, I assign a value to that addr. After
running, program 1 is closed. Then I run program2 with this code. All I want
to do is to see if program 1 assign a value to a addr, will it remains there
and can program 2 read that value. That is the purpose. That you all for
help. The result is No. The memory will be released.

The result depends upon the operating system. In most general-purpose
operating systems you are likely to encounter these days, the result
is what you observed, that the value is -not- preserved between programs.

More than that: if you were to have program1 go to sleep and were to
run program2 while program1 still exists, then the result on most
general-purpose operating systems these days would again be that
program2 does not see the value set by program1.

The results might be substantially different on special-purpose
systems such as for embedded systems (e.g., programming a toaster --
or a completely automated subway car). Also, the result might be
noticably different under older operating systems such as Windows 98.
 
C

Chen shuSheng

I do experiment as what you told. It's exactly as you said if I sleep
program1 and run program 2, result will not be preserved.
My system is windows Xp. I want to know why this happen because program 1 is
running too. Seems that program2 damags what program1 does.
 
W

Walter Roberson

P.S. I am not quit sure about "implementation-defined". Could you pls
explain this?

There is a more precise definition in the C standards.

A quick summary is that implementation-defined behaviour is behaviour
that is not completely determined by the C standard, and that the
implementation has a choice of behaviours, with it being valid
for the implementation to choose any of the allowed behaviours
as long as the implementation documents what it chooses.

"implementation-defined" behaviour is different than "undefined behaviour"
in that for "undefined behaviour", conforming implementations are
allowed to do anything to the state of the program, including
crashing the program (or crashing the subway car, or firing
the nuclear missle, and so on.) The way that any particular
implementation handles undefined behaviour may change from
code fragment to code fragment, and does not need to be consistant,
and does not need to be repeatable -- it could even differ
between different executions of exactly the same part of the code.

If you have code that makes use of what the C standard has
designated as "undefined behaviour", then essentially you should
treat the code as having a random effect -- including, possibly,
randomly choosing to do whatever you were believing the line would
do when you coded it.

"implementation-defined behaviour" is expected to be consistant --
but it might be consistant with something complex and effectively
beyond your control. And "consistant" does not mean "will not crash".
 
W

Walter Roberson

Please do not top-post. Please place your comments after quoting
the section of the message you are commenting on, and please remove
portions of the message that are no longer relevant to the comments.
I have re-arranged what you wrote to standard format to make it
easier to follow.
Walter Roberson said:
I do experiment as what you told. It's exactly as you said if I sleep
program1 and run program 2, result will not be preserved.
My system is windows Xp. I want to know why this happen because program 1 is
running too. Seems that program2 damags what program1 does.

The reason you see this happening is dependant upon your system.
Nearly everything that is dependant upon system behaviour is
considered off-topic in comp.lang.c . For detailed reasons why you
see this behaviour in Windows XP, you should consult a Windows XP newsgroup.


Generally speaking, for general-purpose operating systems these days,
addresses as known by user-level programs are not real physical addresses.
Instead, they are addresses in "virtual memory", and the operating
system automatically substitutes real physical memory addresses
for every reference. When a different user-level program starts
running, tha different program might use exactly the same addresses
as far as the program can tell, but the operating system will
substitute -different- physical memory addresses.

When this is done, logical address 0x246ff5c used in one program might
map to physical address 0x389715635c, but that same logical address
0x246ff5c used in the second program might map to physical address
0x4a25bb8b5c instead. User-level programs that have not been
granted special privileges often -cannot- find out what the
actual physical memory address for anything is -- but that's
up to the operating system. The two programs do not see what
each other has done because they are really accessing different
memory even though they use the same address.

I do not know what is required in Windows XP in order for
a program to have access to arbitrary physical memory. For that
you really need to ask in a Windows XP newsgroup. Also, in
a number of operating systems, there are methods for co-operating
programs to set up "shared" memory, which both programs have
access to (this is not the same as accessing arbitrary physical
memory -- you only get access to the parts that have been
deliberately shared.) I have no idea how to set up such a thing
in XP; consult an XP newsgroup for more information.
 
M

MQ

Chen said:
I do experiment as what you told. It's exactly as you said if I sleep
program1 and run program 2, result will not be preserved.
My system is windows Xp. I want to know why this happen because program 1 is
running too. Seems that program2 damags what program1 does.

In Windows XP, each process has it's own address space. You cannot
directly access the memory space of another process. You need to know
the difference between physical and virtual memory addresses. In your
program, you are accessing a virtual memory address (say 0x12345678).
Both of your programs may have this same memory address mapped into
their address space, but they point to different physical addresses.
So, virtual memory address 0x12345678 in program A may point to
physical address 0xAAA, and virtual memory address 0x12345678 in
program B may point to physical address 0xBBB.

MQ
 
C

Chen shuSheng

Walter Roberson said:
The reason you see this happening is dependant upon your system.
Nearly everything that is dependant upon system behaviour is
considered off-topic in comp.lang.c . For detailed reasons why you
see this behaviour in Windows XP, you should consult a Windows XP
newsgroup.


Generally speaking, for general-purpose operating systems these days,
addresses as known by user-level programs are not real physical addresses.
Instead, they are addresses in "virtual memory", and the operating
system automatically substitutes real physical memory addresses
for every reference. When a different user-level program starts
running, tha different program might use exactly the same addresses
as far as the program can tell, but the operating system will
substitute -different- physical memory addresses.

When this is done, logical address 0x246ff5c used in one program might
map to physical address 0x389715635c, but that same logical address
0x246ff5c used in the second program might map to physical address
0x4a25bb8b5c instead. User-level programs that have not been
granted special privileges often -cannot- find out what the
actual physical memory address for anything is -- but that's
up to the operating system. The two programs do not see what
each other has done because they are really accessing different
memory even though they use the same address.

I do not know what is required in Windows XP in order for
a program to have access to arbitrary physical memory. For that
you really need to ask in a Windows XP newsgroup. Also, in
a number of operating systems, there are methods for co-operating
programs to set up "shared" memory, which both programs have
access to (this is not the same as accessing arbitrary physical
memory -- you only get access to the parts that have been
deliberately shared.) I have no idea how to set up such a thing
in XP; consult an XP newsgroup for more information.

Sorry, I am newbie of Newsgroup. Is this format what you called
non-top-posted?
Thanks for your help.
 
W

Walter Roberson

Chen shuSheng said:
Sorry, I am newbie of Newsgroup. Is this format what you called
non-top-posted?

That was -better-, but you should still trim out the parts that you are
not replying to. Similar to the above: notice that I cut down to just
your question about top-posting, as that is the only part of your
posting I am replying to here.

Quoting the entire posting and then replying is known as "bottom-posting".
People usually dislike "top-posting" more, because they find
top-posting hard to read, but they usually consider "bottom-posting" to be
wasteful. Quoting only what is needed, and mixing quoted material and
comments is called "mid-posting", and that is what people prefer.


Also, your reply should go against the posting you are replying to --
my comment about your top-posting was in a different part of the
thread. You should have replied to the posting in which I made the
comment, not to a handy posting nearby.
 
K

Keith Thompson

A quick summary is that implementation-defined behaviour is behaviour
that is not completely determined by the C standard, and that the
implementation has a choice of behaviours, with it being valid
for the implementation to choose any of the allowed behaviours
as long as the implementation documents what it chooses.

"implementation-defined" behaviour is different than "undefined behaviour"
in that for "undefined behaviour", conforming implementations are
allowed to do anything to the state of the program, including
crashing the program (or crashing the subway car, or firing
the nuclear missle, and so on.) The way that any particular
implementation handles undefined behaviour may change from
code fragment to code fragment, and does not need to be consistant,
and does not need to be repeatable -- it could even differ
between different executions of exactly the same part of the code.

Yes, the program is allowed to do anything, but this is a fairly
narrow meaning of the word "allowed".

The actual definition of "undefined behavior" in the C standard is:

behavior, upon use of a nonportable or erroneous program construct
or of erroneous data, for which this International Standard
imposes no requirements

If your program invokes undefined behavior, it is allowed *by the C
standard* to do literally anything, including (as the standard joke
goes) making demons fly out of your nose. There could well be other
reasons, outside the standard, why it wouldn't be allowed to do this
(such as, in this case, the fact that it's physically impossible).

For example, if your program attempts to modify some random memory
location, the C standard allows it to change memory in some other
running program, but your operating system may forbid it. (Or it may
try to; there are always bugs.)

But you should still be very careful about assuming what your
misbehaving program *cannot* do. It some cases, it's actually
possible for misbehaving software to physically damage hardware.
 
A

Ark

Walter said:
There is a more precise definition in the C standards.

A quick summary is that implementation-defined behaviour is behaviour
that is not completely determined by the C standard, and that the
implementation has a choice of behaviours, with it being valid
for the implementation to choose any of the allowed behaviours
as long as the implementation documents what it chooses.
"implementation-defined behaviour" is expected to be consistant --
but it might be consistant with something complex and effectively
beyond your control. And "consistant" does not mean "will not crash".

While at it: a silly question -
Let's say I made an "implementation-dependent" library of, e.g.,
arithmetic wonders in the assumption that negatives are represented in a
particular format (say, 2's complement).
It is obvious that such a library is portable to a platform/compiler
that documents that much.
The silly question is whether I can "auto-probe" at runtime? If, say,
the signed char named c proves to store all values in 2's complement,
can I be certain (or reasonably believe) that all signed chars are like
that?
Does this belief extend to shorts, ints, etc?
 
W

Walter Roberson

Ark said:
Let's say I made an "implementation-dependent" library of, e.g.,
arithmetic wonders in the assumption that negatives are represented in a
particular format (say, 2's complement).
It is obvious that such a library is portable to a platform/compiler
that documents that much.
The silly question is whether I can "auto-probe" at runtime? If, say,
the signed char named c proves to store all values in 2's complement,
can I be certain (or reasonably believe) that all signed chars are like
that?
Does this belief extend to shorts, ints, etc?

For any one integral or floating type, an implementation would
choose -one- representation, so all variables of that type would
be compatible.

However, for the wider signed types, it is not required that all
bits of storage be used as part of the value determination, and
if you alter those non-value bits through some mechanism
(such as accessing storage as an array of unsigned characters)
then you might happen upon a trap representation that will
cause your program to misbehave (possibly subtly.) It is allowed
that there might be several different bit patterns all of which
are treated as the same arithmetic value, at least for the
wider signed types. *(unsigned long *) &x != *(unsigned long *) &y
might be true even though *(long *) &x == *(long *) &y -- because
the signed version might have padding bits that the unsigned
version might use for value bits.

Some of the unsigned types are guaranteed not to have padding bits;
I would need to review to be sure of which ones.

If you discover that a signed int works a particular way, you should
not assume that signed long works the same way. This is most
especially the case for float and double, which might use completely
different internal representations. It was not uncommon on older
systems for float to be a native floating point format with an
unusual representation, with double being much more standardized.


There -are- portable tests you can use to figure out whether
a particular integral type is two's complement, one's complement,
or signed magnitude.
 
W

Walter Roberson

(e-mail address removed)-cnrc.gc.ca (Walter Roberson) writes:
Yes, the program is allowed to do anything, but this is a fairly
narrow meaning of the word "allowed".
If your program invokes undefined behavior, it is allowed *by the C
standard* to do literally anything, including (as the standard joke
goes) making demons fly out of your nose. There could well be other
reasons, outside the standard, why it wouldn't be allowed to do this
(such as, in this case, the fact that it's physically impossible).

Yes, but those reasons outside of the standard are part of
the implementation. And I did say "anything to the state of the
program", thus (deliberately) precluding doing impossible things
to items not under control of the computer.

So, I'm not sure what the distinction is between what I said
and what you appear to be indicating that I should have
said but think I didn't (other than that you went into more detail) ?
 
A

Ark

Walter said:
For any one integral or floating type, an implementation would
choose -one- representation, so all variables of that type would
be compatible.

However, for the wider signed types, it is not required that all
bits of storage be used as part of the value determination, and
if you alter those non-value bits through some mechanism
(such as accessing storage as an array of unsigned characters)
then you might happen upon a trap representation that will
cause your program to misbehave (possibly subtly.) It is allowed
that there might be several different bit patterns all of which
are treated as the same arithmetic value, at least for the
wider signed types. *(unsigned long *) &x != *(unsigned long *) &y
might be true even though *(long *) &x == *(long *) &y -- because
the signed version might have padding bits that the unsigned
version might use for value bits.

Some of the unsigned types are guaranteed not to have padding bits;
I would need to review to be sure of which ones.

If you discover that a signed int works a particular way, you should
not assume that signed long works the same way. This is most
especially the case for float and double, which might use completely
different internal representations. It was not uncommon on older
systems for float to be a native floating point format with an
unusual representation, with double being much more standardized.


There -are- portable tests you can use to figure out whether
a particular integral type is two's complement, one's complement,
or signed magnitude.

Thank you for the arithmetic stuff.
I meant the silly question a bit wider though: If something is
implementation-defined, how reliable is (or, rather, can be) any
"auto-probing"?
E.g., identically qualified pointers to the same location: are they
represented by the same bit pattern? If not, is their difference always
a 0 anyway (I guess it should)? Is p1==p2 the same as p1-p2==0?
And so on...
 
K

Keith Thompson

So, I'm not sure what the distinction is between what I said
and what you appear to be indicating that I should have
said but think I didn't (other than that you went into more detail) ?

Yes, that was all. It was an elaboration, not a correction.
 
W

Walter Roberson

Ark said:
I meant the silly question a bit wider though: If something is
implementation-defined, how reliable is (or, rather, can be) any
"auto-probing"?

That would depend upon what is being probed.
E.g., identically qualified pointers to the same location: are they
represented by the same bit pattern?


It is certain that identically qualified pointers to the same
location do NOT have to all have the same bit pattern
If not, is their difference always
a 0 anyway (I guess it should)? Is p1==p2 the same as p1-p2==0?

Yes, this behaviour is not implementation-defined. The C standard
requires that identically qualified pointers to the same location
compare equal no matter what their internal representation,
and requires the pointer difference in such case to be 0. Also, in
C99, if you were to write out both pointers using %p format, and
were to read that back in with %p during the same execution (and
the object referenced had continued to exist) then C99 promises that
the two pointers read in will compare equal -- but it doesn't promise
that the text representation of the two will be the same.

In the cases you have indicated, the implementation-defined behaviours
are fairly constrained. There are other examples that are much less
constrained.

An example of an implementation defined behaviour that is much less
constrained is the behaviour of right-shifting negative (signed) values.
An implementation is fully permitted to use an instruction that
fills the top bit with whatever happens to be in the status register
"carry" bit (seriously, several systems have such an instruction).
Thus, the bit filled in might depend upon whether the last
signed integral operation happened to generate a carry or not.
That last signed integral operation might have been somewhere near
the bottom of a loop with the >> happening to be near the top, so the
result of >> might end up depending upon code that has no obvious
connection and which is visually rather some distance away.


The conversion of integer to pointer is another example of
fairly unconstrained implementation defined behaviour. Implementations
are not required to provide such a conversion in -any- meaningful way.

Implementations could literally choose to load a random value into the
pointer (except in the case that the source integer is a constant 0:
that's defined as creating a NULL pointer, but the internal
representation of NULL pointers is not promised to be all-bits-zero.)

Implementations could also, in converting from an integral type to
a pointer, interpret the bits in non-obvious ways. For example, the
last byte (least signficant byte) might be treated as a reference
to an address register, and some permutation of the other bytes
might be treated as the offset relative to that register.
(int *)0x1234 is not necessarily even -close- in virtual memory to
(int *)0x1235 .

Also, the conversion algorithm could depend upon the pointer type being
converted to -- (char *)0x12345 might refer to virtual address 0x12345,
but (int *)0x12345 might refer to virtual address 0x48d14 (e.g.,
0x12345 * sizeof(int) )


In some cases, "implementation-defined" means that the implementation
has to choose one particular meaningful and consistant behaviour
(such as the time represention used for clock() )
but in other cases, "implementation-defined" can include
"behave badly". "Behave badly" is -uncommon- for most
implementation-defined behaviour; on the other hand, it is
not uncommon for factors beyond your effective control to be
at work in implementation-defined behaviour for some arithmetic
operations, such as signed right-shift or behaviour upon overflow.
 

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

Forum statistics

Threads
474,263
Messages
2,571,061
Members
48,769
Latest member
Clifft

Latest Threads

Top