4

Since addresses are numbers and can be assigned to a pointer variable, can I assign any integer value to a pointer variable directly, like this:

int *pPtr = 60000;
5
  • 2
    You can do this, yes. That doesn't mean that it's meaningful, though. Commented Aug 18, 2017 at 23:14
  • you can but not in your way int *p = 10 ; Commented Aug 19, 2017 at 0:29
  • int *p; *p = &10 ; may work for you. but consider possible that memory location maybe not accessible. Commented Aug 19, 2017 at 0:31
  • @EsmaeelE-- *p = &10; will not work since you can't take the address of an integer constant in C. Even if you could, an int may not be able to hold the value. Finally, int *p = 10; declares a pointer to int and stores the value 10 in that variable. int *p; *p = &10; attempts to use the pointer p uninitialized, leading to undefined behavior. Commented Aug 19, 2017 at 0:48
  • 2
    You'll need a cast - int *iPtr = (int *) 60000;. Commented Aug 19, 2017 at 2:35

5 Answers 5

10

You can with an explicit cast:

int *pPtr = (int *)60000;

But unless you're developing for an embedded device with known memory addresses with a compiler that explicitly allows it, attempting to dereference such a pointer will invoke undefined behavior.

You should only assign the address of a variable or the result of a memory allocation function such as malloc, or NULL.

Sign up to request clarification or add additional context in comments.

4 Comments

Actually, IIRC even just creating a pointer that points to an invalid address is UB according to the standard (although the platforms where this actually causes problems are exceedingly rare).
@MatteoItalia Ahhh.. interesting, so on such a system, all pointers would need to be initialized with a valid address upon creation? Yes? Would 'int ptr=&ptr' work for that? I ask because of stackoverflow.com/q/45769003/758133
@MartinJames: I suspect that leaving a pointer not initialized wouldn't be a problem (and that the C standard requires it to work); the core of the issue is that such machines validate pointers when they are loaded in pointer registers, so if you load/calculate an invalid pointer they trap; if you just leave a pointer uninitialized, as long as you don't look at it you are fine (the only thing you can do with it is overwriting it content with NULL or a valid pointer). If you are interested, you may have a look at stackoverflow.com/q/3838855 and stackoverflow.com/q/1866461.
"Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast." This is not the case here so the answer is incorrect.
0

You can but there's a lot of considerations.

1) What does that mean?

The only really useful abstraction when this actually gets used is that you need to access a specific memory location because something is mapped to a specific point, generally hardware control registers (less often: a specific area in flash or from the linker table). The fact that you are assigning 60000 (a decimal number rather than a hexadecimal address or a symbolic mnemonic) makes me quite worried.

2) Do you have "odd" pointers?

Some microcontrollers have pointers with strange semantics (near vs far, tied to a specific memory page, etc.) You may have to do odd things to make the pointer make sense. In addition, some pointers can do strange things depending upon where they point. For example, the PIC32 series can point to the exact same data but with different upper bits that will retrieve a cached copy or an uncached copy.

3) Is that value the correct size for the pointer?

Different architectures need different sizes. The newer data types like intptr_t are meant to paper over this.

3 Comments

Point no. 3 is rather moot as intptr_t, int *, void * all have the same size anyway.
Most of the time. However, near vs far pointers still exist on things like the PIC18, so I'm not convinced that's a universally true statement. For example, void * could be guaranteed to be a near pointer while int * might be a far pointer.
"Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast." This is not the case here so the answer is incorrect.
0

Yes you can. You should only assign the address of a variable or the result of a memory allocation function such as malloc, or NULL.

1 Comment

"Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast." This is not the case here so the answer is incorrect.
0

Sorry for the late answer, but all the posted answers are plain wrong.

int *pPtr = 60000; is invalid C. It is a constraint violation.
See "Pointer from integer/integer from pointer without a cast" issues for details.

Furthermore, we may note the constraints of the cast operator in C (6.5.4):

Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast.

So int *pPtr = (int*)60000; would have been valid C. If the memory location 60000 decimal contains anything meaningful, well that's another story and beyond the scope of the C language. Hardware addresses are almost always expressed in hexadecimal and never in decimal, so it's fishy for that reason alone.

But in case this is a hardware register or some other manner of memory-mapped special thing like a DMA buffer, this code would have been incorrect for another reason, namely because of the lack of volatile. And using int to access such a location is also almost certainly incorrect and a type like uint32_t should have been used instead. To do it proper, follow these guidelines: How to access a hardware register from firmware?

Furthermore, in case the address is invalid because it's out of range, misaligned or in case the resulting pointer variable is a trap representation, the code invokes undefined behavior. Many CPU ISA make a difference between program memory and data memory for example, and the memory mapping unit (MMU) of the CPU may throw a hardware exception in case you assign a data pointer to the program region or a function pointer to the data region. In those cases the assignment itself is undefined behavior and not just the de-referencing of the pointer.

Comments

-1

According to the pointer conversion rules, e.g. as described in this online c++ standard draft, any integer may be converted to a pointer value:

6.3.2.3 Pointers

(5) An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.

Allowing the conversion does, however, not mean that you are allowed to dereference the pointer then.

1 Comment

"Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast." This is not the case here so the answer is incorrect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.