-2

I want to know whether there is a guarantee that memory address is a positive integer, including zero, in intptr_t using the following c/c++ functions (or more)? Maybe you can help me to list their results like this or give me a summary if No,

Function OS Architecture Space Result Range
malloc Linux AMD64 User always positive?
malloc Windows AMD64 User always positive?
HeapAlloc Windows x64 User always positive?
new operator Windows x64 User always positive?
mmap

References

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
samm
  • 620
  • 10
  • 22
  • 4
    All integers in unsigned integer type are positive or zero. – MikeCAT Jul 29 '21 at 13:08
  • 1
    `intptr_t` is useful for representing the *difference* of two addresses or an offset from a specific address, which may be negative. I am not aware of any platform where a negative address value is meaningful. – John Bode Jul 29 '21 at 13:22
  • 3
    A pointer is just a bit pattern. You can view it as positive or negative. It makes no sense to do it from start – Support Ukraine Jul 29 '21 at 13:28
  • 1
    You say "all platforms", but given your table, do you perhaps mean "popular 64 bit platforms"? C compilers have existed for 8 bit computers with 16 bit memory addresses. – Drew Dormann Jul 29 '21 at 13:30
  • 1
    The conversion between a pointer and an `intptr_t` is implementation defined. There is no universal rule. – François Andrieux Jul 29 '21 at 13:30
  • Since your question includes `operator new` are you sure the C tag is appropriate? – François Andrieux Jul 29 '21 at 13:31
  • 3
    @JohnBode `ptrdiff_t` is used for the difference to two pointers. `intptr_t` is used to store the address a pointer contains in a signed integer type. Normally this is a type used for passing pointer values across an API boundry. – NathanOliver Jul 29 '21 at 13:32
  • On every platform I'm familiar with, memory addresses are unsigned. `intptr_t` is signed. Casting a memory address to a `intptr_t` will interpret the bit pattern as a signed integer of sufficient size to hold an address value. That bit pattern as an `int` may result in a negative number. `uintptr_t` will interpret the bit pattern as unsigned. – Eljay Jul 29 '21 at 13:44
  • 1
    Why do you care? A memory address is nothing more than a bit pattern. – Jabberwocky Jul 29 '21 at 13:45
  • @NathanOliver: derp. You're right. I was insufficiently caffeinated when I wrote that. – John Bode Jul 29 '21 at 14:21

4 Answers4

2

You edited your question halfway through, in a way that changed its interpretation considerably. I'm going to answer both versions.

I want to know whether there is a guarantee that memory address is a positive integer

In C and C++, at least, a memory address is a memory address -- it is not necessarily an integer. In these languages, conversions between memory addresses (pointers) and integers are problematic, they require explicit casts, and they are not always guaranteed to work. However, if we do think of memory addresses as being integers, we invariably think of them as being unsigned integers, meaning that they simply can't be negative, on pretty much any platform.

I want to know whether there is a guarantee that memory address is a positive integer, including zero, in intptr_t

Aha. Very different question. intptr_t is a signed type, so now what we want to know is, basically, are there any addresses in the "top half" of the address space, meaning that they have their high-order (most significant) bit set, meaning that they're interpreted as negative numbers if we treat them as a signed type?

When I first learned C, on the 16-bit PDP-11, the stack was at the top of the address space, starting at address 0xffff, or -1, so yes, I saw lots of "negative" addresses, generally any stack address. (In those days we didn't have intptr_t, but we did have addresses that looked negative if we went and treated them as signed integers.)

When Unix was first ported to the 32-bit VAX, and AFAIK for most/all 32-bit versions of Unix and Linux since then, user memory is restricted to the "bottom half" of the virtual memory address space, while the OS itself is mapped into the top half. So on those platforms, it turns out that user addresses will always look positive, which I guess is what you were asking about.

I don't know how Windows does things, and I don't know how things are typically laid out on modern, 64-bit OS's (much less when you've got an OS that's set up to support either 32-bit or 64-bit programs).

So I can't really help you fill in your table. Certainly there is no guarantee that a user address will always be positive when converted to intptr_t. If you were hoping for such a guarantee, if you're thinking of writing a program which makes use of it, I would strongly encourage you to reconsider, if at all possible.

(Over the years, various "clever" programs for various "clever" reasons have tried to usurp one or more bits of a pointer variable, to use as flags for their own purposes, knowing that the bits Just Happened to be insignificant for actual pointer addresses that day. Though these programs may have achieved short-term performance gains, in my experience these tricks have always come to ruin in the end. I'd avoid them like the plague.)

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Re “You edited your question halfway through, in a way that changed its interpretation considerably”: They edited the question seven minutes after posting it, 28 minutes before this or any other answer was posted. – Eric Postpischil Jul 29 '21 at 14:47
  • @EricPostpischil True, but the edit came after or on top of the comment I posted, which I later turned into the first half of this answer. – Steve Summit Jul 29 '21 at 14:51
0

In C (and C++) there is a clear distinction between the types integer and pointer (memory address of an object, generic form: void*).

Both types are compatible types and of the same group, namely scalar types.

The type ptrdiff_t is a signed integer type returned when subtracting two pointers. Since C99/C++11, with the introduction of fixed width integer types, we also have the types intptr_t and uintptr_t, integer types capable of holding a pointer.

So, to conclude, if you're talking of an address (pointer), you're not talking of an integral type. Since both are scalar types, they're compatible to each other and therefore (in some circumstances) interchangeable. But never equal. Therefore, (i think) your question is meaningless.

Reference:

Erdal Küçük
  • 4,810
  • 1
  • 6
  • 11
0

I want to know whether there is a guarantee that memory address is a positive integer

Any HW engineer will view a memory address as a positive number.

But in C programming it makes no sense. In programming we have pointers and they are not integers. They are some printable bit pattern (implementation defined). Printing a pointer can give you

FFFFFFFF00112233

You can look at it as being positive or negative as you like but it doesn't make sense. According to the C standard they are not integers and consequently neither positive nor negative.

You can convert pointers to intptr_t and uintprt_t. These are signed and unsigned respectively. So the range you can get depends on what you want.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
-1

When you convert the pointer to intprt_t then if the value of the pointer converted to uintptr_t is larger than INTPTR_MAX then conversion to intptr_t will be negative (assuming two's compliment signed integer format).

0___________
  • 60,014
  • 4
  • 34
  • 74