How does a pointer to a constant integer number in C? - c

I try use a pointer to a constant integer number in C:
void *p = NULL;
p = (int *) 1;
printf("p=%d\n", *(int *)p);
but I got a segment fault.....
I cannot figure out how a pointer to a constant number in C w/o declaring a variable.

You are not taking the pointer to a constant but you are converting the constant to a pointer. You should do something like:
const int one = 1;
const int *p;
p = &one;
You cannot however do something like:
p = &1;
since literal constants haven't a memory location.

*(int *)p
You are derefrencing p, which is a pointer that has a value of 1. It's unlikely to be a valid address, segmentation fault is not a surprise.
P.S: p is not a pointer to const integer, it has a value of a constant integer.

p = (int *) 1; does not set the pointer p to point to a memory location with value 1. This sets the value of the pointer to 1, i.e, sets the pointer to point to the memory location with address 1.

try this:
void *p = NULL;
const int num = 1;
p = (int*)(&num);
printf("p=%d\n", *((int *)p));

Related

dereferencing pointer to a pointer with one Asterisk [duplicate]

This question already has answers here:
Pointer to pointer clarification
(16 answers)
Closed 1 year ago.
#include <stdio.h>
int main(){
int integer = 300;
int* p = &integer;
int** pp = &p;
printf("*pp = %i", *pp);
}
My question is what is actually *pp? What does it mean to print the value in the address of *p ?
It is a reference to the integer converted to an integer value.
To print the reference you should use %p format specifier instead of the %i format specifier.
[pp] -> [p] -> [integer]
If you modify the program you can see the references and how they are chained:
int main()
{
int integer = 300;
int* p = &integer;
int** pp = &p;
printf("pp = %p *pp = %p\n",(void *)pp, (void *)*pp);
printf("&integer = %p &p = %p\n", (void *)&integer, (void *)&p);
}
pp = 0x7fffb6adc7d8 *pp = 0x7fffb6adc7e4
&integer = 0x7fffb6adc7e4 &p = 0x7fffb6adc7d8
#include <stdio.h>
int main(){
int integer = 300;
int* p = &integer;
int** pp = &p;
printf("**pp=%d\n", **pp);
printf("*p=%d\n", *p);
printf("*pp = %p\n", *pp);
printf("p=%p\n", p);
printf("&integer=%p\n", &integer);
printf("&(*p)=%p\n", &(*p));
printf("pp=%p\n", pp);
printf("&p=%p\n", &p);
}
Since &(*p) is simply p, yes *pp is the address of *p.
Since %i is integer but what you want to print is pointer. So I changed it to %p.
I'm not a pro in C programming, but I believe I have a decent knowledge of pointers.
So, to understand what is *pp, you need to understand what is * operator used for?
It is no doubt used for multiplication, but it is also used for pointer de-referencing.
So when I say *pp, it means the value of pp i.e. what is stored in pp. Each defined variable in C will have a memory space of its own. So *pp means what is stored in the memory space that was given to the variable pp.
In your case,
int integer = 300;
A variable of type integer named integer is declared and given the value 300
int* p = &integer;
A pointer that needs to point to an integer variable is declared and given the address of integer.
int** pp = &p;
A pointer that needs to point to an integer variable is declared and given the address of p
printf("*pp = %i", *pp);
*pp means printing the value which is stored in pp i.e. address of p
**pp means printing the value which is stored in the value which is stored in p i.e. 300
As I explained earlier, each variable has a memory space of its own, and each memory space will have an address assigned to it, so that it can be identified (the way we have an email address which is used to contact us via email or a postal address which is used to contact us via post).
Hope this answers your question. Do ask follow-up questions if any.
Cheers..!!

What does *p mean when **p is already declared

Code
short **p = (short **)malloc(sizeof(short *));
*p = malloc(sizeof(short));
**p = 10;
printf("**p = %d", **p);
Output
**p = 10
In this code, a multiple pointer **p is declared and *p is used without any declaration(maybe it's by **p).
What does *p mean in my case? Sorry for very simple question.
I saw C standard and stack overflow, but I couldn't find out something.
For any array or pointer p and index i, the expression p[i] is exactly equal to *(p + i) (where * is the unary dereference operator, the result of it on a pointer is the value that the pointer is pointing to).
So if we have p[0] that's then exactly equal to *(p + 0), which is equal to *(p) which is equal to *p. Going backwards from that, *p is equal to p[0].
So
*p = malloc(sizeof(short));
is equal to
p[0] = malloc(sizeof(short));
And
**p = 10;
is equal to
p[0][0] = 10;
(**p is equal to *(*(p + 0) + 0) which is equal to *(p[0] + 0) which is then equal to p[0][0])
It's important to note that the asterisk * can mean different things in different contexts.
It can be used when declaring a variable, and then it means "declare as pointer":
int *p; // Declare p as a pointer to an int value
It can be used to dereference a pointer, to get the value the pointer is pointing to:
*p = 0; // Equal to p[0] = 0
And it can be used as the multiplication operator:
r = a * b; // Multiply the values in a and b, store the resulting value in r
short **p = (short **)malloc(sizeof(short *));
This line declares a pointer to a pointer p. Additionally the value of p is set to the return value from malloc. It is equivalent to
short **p;
p = (short **)malloc(sizeof(short *));
The second line
*p = malloc(sizeof(short));
Here *p is the value of p. *p is of type pointer. *p is set to the return value of malloc. It is equivalent to
p[0] = malloc(sizeof(short));
The third line
**p = 10;
**p is the value of the value of p. It is of type short. It is equivalent to
p[0][0] = 10
In effect what the code above does is to allocate a 2D array of short, then allocate memory for the first row, and then set the element p[0][0] to 10.
As a general comment on your code, you should not use typecast in malloc. See Do I cast the result of malloc?
What does *p mean when **p is already declared?
short **p = (short **)malloc(sizeof(short *));
(better written as)
short **p = malloc (sizeof *p);
Declares the pointer-to-pointer-to short p and allocates storage for a signle pointer with malloc and assigns the beginning address for that block of memory to p. See: In C, there is no need to cast the return of malloc, it is unnecessary. See: Do I cast the result of malloc?
*p = malloc(sizeof(short));
(equivalent to)
p[0] = malloc (sizeof *p[0]);
Allocates storage for a single short and assigns the starting address for that block of memory to p[0].
**p = 10;
(equivalent to)
*p[0] = 10;
(or)
p[0][0] = 10;
Assigns the value 10 to the dereference pointer *p[0] (or **p or p[0][0]) updating the value at that memory address to 10.
printf("**p = %d", **p);
Prints the value stored in the block of memory pointed to by p[0] (the value accessed by dereferencing the pointer as *p[0] or **p)
The way to keep this straight in your head, is p is a single pointer of type pointer-to-pointer-to short. There are 2-level of indirection (e.g. pointer-to-pointer). To remove one level of indirection, you use the unary * operator, e.g.
*p /* has type pointer-to short */
or the [..] also acts as a dereference such that:
p[0] /* also has type pointer-to short */
You still have a pointer-to so you must remove one more level of indirection to refernce the value stored at the memory location pointed to by the pointer. (e.g. the pointer holds the address where the short is stored as its value). So you need:
**p /* has type short */
and
*p[0] /* also has type short */
as would
p[0][0] /* also has type short */
The other piece to keep straight is the type controls pointer-arithmetic. So p++ adds 8-bytes to the pointer-to-ponter address so it now points to the next pointer. If you do short *q = (*p)++; (or short *q = p[0]++, adds 2-bytes to the address for the pointer-to-short, soqnow points to the nextshortin the block of memory beginning at*p(orp[0]`). (there is no 2nd short because you only allocated 1 -- but you get the point)
Let me know if you have further questions.
Let me put it in different way,
consider an example,
int x;
int *y = &x;
int **z = &y;
x = 10;
Which simplifies to this,
Note: Only for illustration purpose I have chosen address of x,y,z as 0x1000,0x2000,0x3000 respectively.
What does *p mean in my case?
In short the snippetshort **p = (short **)malloc(sizeof(short *)); is dynamically allocating a pointer to a pointer of type short i.e same asy in my example.

Pointer difference between int *val = otherVal and int val = otherVal

I am little confused and tried finding explanation but all "difference" questions asked are about type *name vs type* name which i know answer of.
I have code like this:
int a = 1;
printf("a = %d", a); // Prints 1
int *pt = a;
printf("pt = %d", pt); // Prints 1
*pt = 2; // Crash why? What am i pointing to here?
&pt = 2; // Not even compiling since
pt = 2; // Works
printf("pt = %d\n", pt); // Prints 2
printf("a = %d\n", a); // Prints 1
I know in order to change value of a i should have done int *pt = &a and then *pt = 2 and that is not my question.
My question is in this case, is using int *pt = a same as using int pt = a or is there any advantage of using it as pointer?
int a = 1;
...
int *pt = a;
Attempts to store the value 1 as the address held by pointer pt. Any dereference of pt is guaranteed to SegFault as address 1 is well down at the bottom of the system-reserved memory range -- which you have no ability to access, resulting in an access violation and SegFault.
What Is A Pointer?
A pointer is simply a normal variable that holds the address of something else as its value. In other words, a pointer points to the address where something else can be found. Where you normally think of a variable holding an immediate values, such as int a = 5;, a pointer would simply hold the address where 5 is stored in memory, e.g. int *b = &a;. It works the same way regardless what type of object the pointer points to. It is able to work that way because the type of the pointer controls the pointer arithmetic, e.g. with a char * pointer, pointer+1 point to the next byte, for an int * pointer (normal 4-byte integer), pointer+1 will point to the next int at an offset 4-bytes after pointer. (so a pointer, is just a pointer.... where arithmetic is automatically handled by the type)
So in your case:
int a = 1;
...
int *pt = &a;
Will assign the address where a is stored in memory to the pointer variable pt. You may then access the value at that address by dereferencing pt (e.g. *pt)
What you are doing is setting the address to which the pointer pt points to, to what a is currently holding (1 in your case). Since *a is most definitely not a valid and accessible address you will most likely get a segmentation fault when trying to dereference it. This is somewhat the same as if you are creating a null pointer by int *pt = 0 but instead of 0 you use whatever is in a.
Keep in mind that there is probably something funky going on with converting a signed int to an address which only makes the whole thing even worse.

Does ptr = &a and *ptr = a mean the same?

In the book it explains:
ptr = &a /* set ptr to point to a */
*ptr = a /* '*' on left:set what ptr points to */
They seem the same to me, aren't they?
No. The first one changes the pointer (it now points at a). The second one changes the thing that the pointer is pointing at.
Consider:
int a = 5;
int b = 6;
int *ptr = &b;
if (first_version) {
ptr = &a;
// The value of a and b haven't changed.
// ptr now points at a instead of b
}
else {
*ptr = a;
// The value of b is now 5
// ptr still points at b
}
Well, no. But to explain the similar behaviour, Adding to Oli Charlesworth's answer:
Consider:
int a = 5;
int* ptr = new int;
if(first_version) {
ptr = &a;
//ptr points to 5 (using a accesses the same memory location)
} else {
*ptr = a;
//ptr points to 5 at a different memory location
//if you change a now, *ptr does not change
}
edit: sorry for using new (c++ not c) but the pointer thing does not change.
No, in ptr = &a you are storing the address of variable 'a' in variable 'ptr'
i.e., something like ptr=0xef1f23.
in *ptr = a you are storing the value of variable 'a' in pointer variable '*ptr'
i.e., something like *ptr=5.
Both are not same.
If u modify the value of a = 10. Then print again *ptr. It will print only 5. not 10.
*ptr = a; //Just copies the value of a to the location where ptr is pointing.
ptr = &a; //Making the ptr to point the a
*ptr=&a C++ compiler will genrate error becoz u r going to assign addres to adres
ptr=&a,this is true here ptr working like variable and &a is a addres of a which contain some value
check and try
int *ptr,a=10;
ptr=&a;output=10;
*ptr=&a signifies that our pointer is pointing towards address of the variable a
while
*ptr=a signifies that our pointer is pointing towards value a
*ptr = &a is not technically correct.
int *ptr = &a; is correct ..... Way (i)
(or)
int *ptr;
ptr = &a; is correct ..........Way (ii)
Here *ptr is a pointer to integer datatype.
int *ptr;
*ptr = a; This means ptr becomes a NULL pointer [i.e. it does not point to any memory location]. *ptr holds the value of a.

Given the address of a pointer, how do I get what it points to?

If I am given the address of a pointer, how do I get what the pointer points to?
You might mean:
/**
* #param pointer_to_pointer_to_int: the address of a pointer to an integer.
**/
void function_that_takes_pointer_to_pointer(int **pointer_to_pointer_to_int) {
int the_int = **pointer_to_pointer_to_int;
printf("The pointer points to %d\n", the_int);
}
Assuming it is a valid pointer, you can dereference it using the unary * operator:
int *ptr = ...;
int x;
x = *ptr;
The unary * operator.
int *ptr = malloc(sizeof(int));
*ptr = 45;
printf("address: %p, value: %d", ptr, *ptr);
The most common way to be given the address of a pointer is through a pointer to a pointer. If the value the pointer points to is an integer, the type of the address of the pointer is int **.
To get the pointer to the integer, you need to dereference the double pointer. Then you can dereference the integer pointer to get the integer value.
To dereference a pointer, use the * operator.
int **double_pointer = given;
int *int_pointer = *double_pointer;
int value = *int_pointer;
You can also chain the dereferences to do that on one line.
int **double_pointer = given;
int value = **double_pointer;
The unary * operator returns or sets the value at a memory location.
For example:
int val = 42;
int* ptr = &val;
assert(val == *ptr);
If you have the address of a pointer, you would write **pointerpointer.
Going off of RedX's comment, If you have a situation like
void foo(void *ptr)
{
...
}
where the value of ptr is a pointer to a pointer to int, for example, you could do something like
void foo(void *ptr)
{
int x = **((int **) ptr);
...
}
Basically, you cast ptr to int **, then double-dereference it.
If you don't know what the target type is ahead of time (e.g., the function is meant to handle pointers to multiple types), then you're going to have to figure out a way to encode that type information in a second argument and pass it to the function.
There are two possible answers to your question depending on whether the compiler has a clue about the data that's referred or not.
Declaring a pointer of type int *, char * or mytype * instructs the compiler that a later attempt to dereference it using the unary * operator must yield a result of int, char or mytype respectively.
In the other case you would normally store a pointer either in a void * (generic, untyped pointer) or in a uintptr_t (an unsigned int the same size of a pointer, but without pointer semantics). In such a case the compiler doesn't have a clue how to interpret the dereferencing operator, so you must explicitly cast such a pointer to another pointer type, and only then dereference it:
int x = 5;
void *p = &x; /* p now points to an int, but the compiler doesn't know it */
printf("%d\n", *((int *) p)); /* we know what we did and don't rely on the compiler */
printf("%d\n", *p); /* compile-time error, dereferencing has undefined semantics */
Note that in compiled, unmanaged languages like C there is no runtime information about what kind of data a pointer is pointing to, unlike languages like Java where you can use the instanceof operator to check what a reference is really pointing to at runtime.

Resources