What does this number stand for - c

I was simply trying out this code which is saw in a tutorial
#include <stdio.h>
int main() {
int a = 34;
int *ptra = &a;
printf("%d\n", ptra);
return 0;
}
Here when I run this code I get a number as an output. The number was 6422216.
What does this number stand for ?
(I was trying to learn pointer arithmetics)

Your program prints out the memory address of where the integer a is stored and I'll explain why but firstly you need to know what the symbols stand for.
* - is used to declare a pointer and when placed before a address it will give you what is stored at that address
& - will give you the address of the variable written after it
So, first you assign the integer a value of 34
int a = 34;
Then you create a pointer of a integer called ptra and assign it the memory address of where the integer a is stored
int *ptra = &a;
And finally you print the value of ptra which is the memory address of where the integer a is stored
printf("%d\n", ptra);
If you would wan to print out the value of a through the integer, then you should replace ptra with *ptra in the printf function.

The behavior of the code sample is actually undefined because you pass a value of type int * where printf expects an int as the argument for conversion %d.
The code may be corrected as printf("%p\n", (void *)ptra); or possibly printf("%llu\n", (long long)ptra);
The value printed is the address of the variable a, which is system specific and may change from one run of the program to another, as is the case on OS/X that implements address space randomisation to increase the difficulty for hackers to exploit some program flaws.
To cut a long story short, the answer to your question What does this number stand for? is the number is the numeric value of the address of variable a which is stored in the pointer ptr. Since addresses can be wider than the int type, you should use a longer type such as long long, preferably unsigned:
printf("%llu\n", (long long)ptra);

Related

Dereference pointer *p vs ("%s", p)

I'm new to C and currently learning about Pointers. All I know is a pointer is basically a variable that contains the address of another variable and to get its data we need dereference pointer :
int i = 10;
int *pi = &i;
printf("%d",*pi);
But watching some tutorials on yt I also see
char *p = "Hello";
printf("%s",p); //print out Hello//
I also test it myself
int *i = 10;
printf("%d",i); //print out 10//
I have searched about it and know it's a kind of read-only memory instead of char []. But p and i here are pointers and how can they work with %s and %d directly but not dereferencing *i *p. Can anyone explain it to me pls.
A pointer doesn't necessarily contain address of another variable, it contains an address of some data, which can but doesn't need to be in a variable. For example, the pointer may point to dynamically allocated data, or to data that is part of an array, or to static data that ships with the executable.
In case of char *p = "hello", p points to the first character of a character array prepared by the compiler, and which contains the letters hello followed by a terminating zero character. The %s specifier is designed to receive such a pointer and print the letters up to the zero character, which is why it works.
Your second example, where you print a pointer using %d is quite different in nature. It abuses the fact that addresses have integer representations, and that T *x = <some integer> implicitly casts the integer to the corresponding memory address. In your case you create an invalid pointer pointing to the invalid address 10. Then you proceed to call printf with the %d specifier without dereferencing the pointer. Since %d expects an integer, and the address is also internally represented as an integer, this prints the invalid address 10 the pointer points to. However, pointers and integers don't have compatible memory representations, so this kind of code only works by accident, and exhibits undefined behavior.
To generalize the answers already given, a pointer is simply a variable that contains a memory address. How the code attempts to use that memory address depends on the context you give to it. A pointer can point to data, or even code, in the form of a function pointer. You could even assign any arbitrary value you want to a pointer, and the code will attempt to use it, though that likely will fail or give unpredictable results.
It's perfectly legal to do this:
int *i = (int *)0x12345678;
and dereferencing that pointer (int x = *i;) is also perfectly legal, but will almost certainly fail, because 0x12345678 is likely not an address that is valid when your code runs. Even if it is, the code generated by the C compiler will attempt to access those bytes in a manner that may not correspond to whatever is stored there. In the above case, if you're on, say, a 32-bit x86, the code will interpret the 4 bytes starting at 0x12345678 as a 32-bit signed integer in little-endian format. Whatever is actually there may not result in a usable value.
hi Have Following Have Example Of Pointer With Array
enter code here
#include<stdio.h>
#include<conio.h>
void main()
{
int x,*px,i,**pxx;
x=10;
px=&x; //Right Way To iniFor Pointer
pxx=&px+1; //store address of another pointer
clrscr();//we use px+1 because have 2 address 1 is x and 2 px
printf("\n\n passed value of x in pointer");
printf("\n\n the value of x:-%d",x);
printf("\n the value of px:-%d",*px);//Using * u access a value
printf("\n the value of pxx:-%d",**pxx);
printf("\n\n the address of pointer variable");
printf("\n\n the &x address:-%p",&x);
printf("\n the px &address:-%p",&px); //using %p Or %x Acces address
printf("\n The address of pxx:%p",&pxx);
for(i=0;i<5;i++)
{
px=px+1;
*px=i;
printf("\n%d %p",*px,px);
}
printf ("\n\nThe array of Pointer\n");
for(i=0;i<5;i++)
{
pxx=pxx+1;
printf("\n%d %p",*pxx,pxx);
}
getch();
}
in this example pointer used as a array
**pxx is have 2 address 1 is x 2 is pxx
that reason we used pxx=&px+1 to access address of px
*-represents value at certain variable.
&-represents address of certain variable.
*p=10 let's say the address of p might be "662543" so now by you have stored the value 10 in the address "662543".
and nor if you print
*p - output will be 10, and
&p- output will be 662543.
and talking about the % sign its a format specifier. like %d for integer, %f for float and %s for string etc.
and difference between %d and %i is as follows-
%d takes integer value as signed decimal integer i.e. it takes negative values along with positive values but values should be in decimal otherwise it will print garbage value.( Note: if input is in octal format like:012 then %d will ignore 0 and take input as 12) Consider a following example.
%i takes integer value as integer value with decimal, hexadecimal or octal type.
To enter a value in hexadecimal format – value should be provided by preceding “0x” and value in octal format – value should be provided by preceding “0”.

Short to Int typecasting doesn't work why?

#include <stdio.h>
main()
{
short vShort=3;
int *iInt=(int *)&vShort ;
printf("Value of short: %d\n",vShort);
printf("Value iof short: %d\n",*iInt);
}
I wrote this code but this variable is printing valus as below.
Sizeof Int-4
Sizeof Short - 2
It is also not working when I do "int*iInt=&vShort ;" it gives same output.
output:
Value of short: 3
Value iof short: 196608
Here,
int *iInt=(int)&vShort
You're casting the address of a variable to int (which is undefined behaviour, or at the very least implementation defined because an integer may not be big enough to hold the pointer's value, only uintptr_t is).
If you want to "cast" a short to an int, just assign it, integer promotion will take care of everything:
short s = 3; // note that this line already technically casts the integer literal 3 to type short
int i = s;
If you want a pointer to an int value, you'll need to either create a local variable and take its address, or allocate memory for it with malloc:
short s = 3;
int i; // if you add "= s" here you can drop the last line
int* iptr = &i;
*iptr = s;
Actually this type of code was already present in our system where to remove warning developer typecasted short to int. Thats why i posted this question whats wrong with this code.

C Programming Simple Pointers

I'm a beginner at learning pointers. Here is my code. (Note: I'm still trying to get my head around pointers so my code won't be clean.)
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]){
int a = 1;
char b = 's';
double c = 3.14;
int *ptra;
int *ptrb;
int *ptrc;
ptra = &a;
ptrb = &b;
ptrc = &c;
printf("I initialised int as %d and char as %c and double as %.2f\n", a, b, c);
printf("The address of A is %p and the contents of A is %d\n", ptra, *ptra);
printf("The address of B is %p and the contents of B is %c\n", ptrb, *ptrb);
printf("The address of C is %p and the contents of C is %.2f\n", ptrc, *ptrc);
I expected the following output:
I initialised int as 1 and char as s and double as 3.14
The address of A is 0xbf933094 and the contents of A is 1
The address of B is 0xbf933093 and the contents of B is s
The address of C is 0xbf933098 and the contents of C is 3.14
But instead I get this:
I initialised int as 1 and char as s and double as 3.14
The address of A is 0xbf933094 and the contents of A is 1
The address of B is 0xbf933093 and the contents of B is s
The address of C is 0xbf933098 and the contents of C is 427698.00000
Can someone help for the large number I got when printing the contents of C? Why don't I get 3.14? (The number is actually longer than that but it didn't fit into this textbox. :-))
You are declaring ptra, ptrb and ptrc as pointers to ints. But the type of a pointer is based on what it points to, so it really should be:
int *ptra;
char *ptrb;
double *ptrc;
In your specific case, your program is trying to interpret a double value through an int pointer. Since the sizes of these data types differ on your machine, some of the bits of the double get discarded and you end up with the strange number you're seeing.
This may not always happen the same way - the result of accessing something through the wrong type of pointer is not defined by the C language, but it still might compile. C programmers refer to this as undefined behaviour (a phrase you should really come to terms with if you want to learn C!).
There is also the fact that when you call printf, you need to give it variables of the type it expects from the format string. So if you give it a format string where the first placeholder is %.f, you must give it a first argument that's a double. If you don't, printf will also exhibit undefined behaviour and could do anything (the undefined behaviour may be strange output, crashing, or simply putting out the number you expect... until the worst possible moment).
Your pointers are all of type int. That is not correct. Replace those by
int *ptra;
char *ptrb;
double *ptrc;
Because your pointers are all int*. If you want it to dereference to a double, you need it to be double*. Your compiler should have warned you about incompatible pointer assignment.
You should declare pointers using the corresponding type.
int *ptra;
char *ptrb;
double *ptrc;
you need to change your pointer type to match your data type so the size will be set accordingly.
char *ptrb;
double *ptrc;
If I can just say a few words about typed pointers.
Pointers with a type (as opposed to void* pointers) know how many bytes to advance in memory. For example on 32 bit systems and integer pointer would typically advance four bytes in memory when iterating through an array containing integer values.
A char pointer (guaranteed by the C standard to be always 1 byte) would naturally advance 1 byte at a time.
Let me illustrate this with a small code snippet:
#include <stdio.h>
int main()
{
char array [] = "This is a char array.";
int* int_ptr;
char* char_ptr;
char_ptr = array; /* This is okay, we have a char array and we assign its address to a char pointer */
int_ptr = array; /* It will complain but let's go along with it */
printf("%p, %p, %p\n", array, char_ptr, int_ptr); /* They should all point to the same address in memory */
printf("%p\n", ++char_ptr); /* it will have advanced by one byte */
printf("%p\n", ++int_ptr); /* it will have advance by four bytes */
return 0;
}
I have the following output on my machine:
$ ./a.out
0xbf8b85d2, 0xbf8b85d2, 0xbf8b85d2
0xbf8b85d3
0xbf8b85d6
As you can see they have indeed advanced as we predicted. It is fairly obvious this can cause all sorts of problems when we start dereferencing our pointers and they don't match the underlying type.
Regarding void* pointers, arithmetic on them is illegal.
here the pointer ptrc is referring to the addressof varaible whose data type is integer but you are using it for double.

I have an error in a C program. It says that %d requires int, but is reading int *. What exactly is an int *?

I have an error in a C program. It says that %d requires int, but is reading int *. I used some mod10 functions before, to separate a 4 digit number. After manipulating each digit, with nothing more than division and other mod10's, I put the numbers back together as a 4 digit integer, and tell it to print it. With using %d in the printf line, i get an error back saying that %d is looking for an 'int', and it is finding an 'int *'. What exactly is an 'int *', and any ideas on what went wrong here?
An int * is a pointer to an int.
To get the value of a pointer to a variable use * in front of the variable name.
To get the address of a variable use & before it's name.
Example;
int c = 1, d= 0;
int *e = &c; // assign address of c to pointer e
d = *e; // assign value that c points to, to d
printf("%d",d); // print int value of d
printf("%d",*e); // same output as line above. print value c points to
Here is a little tutorial on pointers.
An int* is a pointer to an integer rather than an integer itself. C has the concept of pointers which are variables that can point to other variables, allowing you to do all sorts of wondrous things.
Without seeing your code, it's a little difficult to see what you've done wrong, but you can get a pointer by declaring it so:
int * pInt;
or by using the address-of operator:
doSomethingWith (&myInt);
An int* is a pointer to an integer, instead of an integer variable. This means that instead of holding some data, it holds a reference to a location in memory where some data is residing. If you want to access the data at the location that it references then you need to dereference the pointer.
To do this you do this:
int a = 100; //an integer variable
int* b= &a; //b is now the location of a in memory
cout << *b; //This dereferences b to the data in a, and prints 100
Hope this helps, any corrections anyone please let me know.
Show us (by editing it into your question) the line of code it's complaining about.
To answer your question, an int* is a pointer to an int. For example, given
int i;
int *p;
i and *p are of type int, and &i and p are of type int*.
Look up "pointers" in your C textbook.
Also, the comp.lang.c FAQ is an excellent resource; section 4 discusses pointers. (But it's mostly intended to answer questions you'll have after you've started to understand the concepts.)
int * is a pointer to an integer.
Please post the line of code that is flagged, the error message and the line that declares your variable.

Confusion with pointers

I am trying to learn C. The reading I've been doing explains pointers as such:
/* declare */
int *i;
/* assign */
i = &something;
/* or assign like this */
*i = 5;
Which I understand to mean i = the address of the thing stored in something
Or
Put 5, or an internal representation of 5, into the address that *i points to.
However in practice I am seeing:
i = 5;
Should that not cause a mismatch of types?
Edit: Semi-colons. Ruby habits..
Well, yes, in your example setting an int pointer to 5 is a mismatch of types, but this is C, so there's nothing stopping you. This will probably cause faults. Some real hackery could be expecting some relevant data at the absolute address of 5, but you should never do that.
The English equivalents:
i = &something
Assign i equal to the address of something
*i =5
Assign what i is pointing to, to 5.
If you set i = 5 as you wrote in your question, i would contain the address 0x00000005, which probably points to garbage.
Hope this helps explain things:
int *i; /* declare 'i' as a pointer to an integer */
int something; /* declare an integer, and set it to 42 */
something = 42;
i = &something; /* now this contains the address of 'something' */
*i = 5; /* change the value, of the int that 'i' points to, to 5 */
/* Oh, and 'something' now contains 5 rather than 42 */
If you're seeing something along the lines of
int *i;
...
i = 5;
then somebody is attempting to assign the address 0x00000005 to i. This is allowed, although somewhat dangerous (N1256):
6.3.2.3 Pointers
...
3 An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant.55) If a null pointer constant is converted to a
pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
...
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.56)
...
55) The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant; see 7.17.
56) The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment.
Depending on the architecture and environment you're working in, 0x00000005 may not be a valid integer address (most architectures I'm familiar with require multibyte types to start with even addresses) and such a low address may not be directly accessible by your code (I don't do embedded work, so take that with a grain of salt).
I understand to mean i = the address of the thing stored in something
Actually i contains an address, which SHOULD be the address of a variable containing an int.
I said should because you can't be sure of that in C:
char x;
int *i;
i = (int *)&x;
if i is a pointer, than assign to it something different to a valid address accessible from you program, is an error an I think could lead to undefined behavior:
int *i;
i = 5;
*i; //undefined behavior..probably segfault
here's some examples:
int var;
int *ptr_to_var;
var = 5;
ptr_to_var = var;
printf("var %d ptr_to_var %d\n", var, *ptr_to_var); //both print 5
printf("value of ptr_to_var %p must be equal to pointed variable var %p \n" , ptr_to_var, &var);
I hope this helps.
This declares a variable name "myIntPointer" which has type "pointer to an int".
int *myIntPointer;
This takes the address of an int variable named "blammy" and stores it in the int pointer named "myIntPointer".
int blammy;
int *myIntPointer;
myIntPointer = &blammy;
This takes an integer value 5 and stores it in the space in memory that is addressed by the int variable named "blammy" by assigning the value through an int pointer named "myIntPointer".
int blammy;
int *myIntPointer;
myIntPointer = &blammy;
*myIntPointer = 5;
This sets the int pointer named "myIntPointer" to point to memory address 5.
int *myIntPointer;
myIntPointer = 5;
assignment of hard-coded addresses, is something that shouldn't be done (even in the embedded world, however there are some cases where it's suitable.)
when declaring a pointer, limit yourself to only assign a value to it with dynamiclly allocated memory(see malloc()) or with the & (the address) of a static (not temporary) variable. this will ensure rebust code, and less chance to get the famous segmentation fault.
good luck with learning c.

Resources