c program pointer - c

I am trying some programs in c face a problem with this program
can any one tell me what is the problem with this and i also want to know that when in the above case if the pointer value is incremented then will it over write the previous value address as
#include<stdio.h>
int main()
{
int a=9,*x;
float b=3.6,*y;
char c='a',*z;
printf("the value is %d\n",a);
printf("the value is %f\n",b);
printf("the value is %c\n",c);
x=&a;
y=&b;
z=&c;
printf("%u\n",a);
printf("%u\n",b);
printf("%u\n",c);
x++;
y++;
z++;
printf("%u\n",a);
printf("%u\n",b);
printf("%u\n",c);
return 0;
}
suppose that the value we got in the above program (without the increment in the pointer value )is
65524
65520
65519
and after the increment the value of the pointer is
65526(as 2 increment for the int )
65524(as 4 increment for the float )
65520(as 1 increment for the char variable )
then if in that case will the new pointer address overwrite the content of the previous address and what value be contained at the new address

You can't just increment x,y,z like that.
You have no guarantee that they are laid out in memory in that order - the memory address after 'x' could be anything.
Edit just to clarify:
Yes you can increment a pointer, but you have to be sure that you 'own' the memory that you are then pointing to - typically memory in a string or an array.
You can't assume that separate variables are adjacent to each other in memory - in fact different types will be probably be spaced out so that each new one starts at a 4byte boundary.

First of all, I assume your calls to printf are supposed to display the values of x, y and z, or the addresses of a, b, and c, correct? In that case you need to change them to:
printf("%p\n", x);
printf("%p\n", y);
printf("%p\n", z);
These will take into account the size of a pointer on your processor, if that is different from the size of an int. They will also print the address in hexadecimal, which is much more common since addresses can get quite large.
and after the increment the
value of the pointer is 65526(as 2
increment for the int )
Assuming you're on a platform where int is 2 bytes (on most modern home PCs int is probably 4 now).
then if in that case will the new
pointer address overwrite the content
of the previous address and what value
be contained at the new address
......plz help
You haven't actually dereferenced any of the pointers here. So the memory occupied by a, b, and c is still untouched; all you've done is changed what x, y, and z are pointing to. If you were to dereference one of the pointers after incrementing it, you would be modifying memory past the variable it initially pointed to. So if a is at address 65526 decimal and int is 2 bytes:
int *x = &a; // x points to the integer at "65526" (a)
x++; // x points to the integer at "65528", a is still at 65526
*x = 5; // you've just modified the memory at addresses 65528 and 65529.
If 65528 or 65529 contained some other important data (like b or c) you've just corrupted your program's state.

If you're trying to output the values of the pointers x, y and z, then you need to change the last six printf statements like so:
printf("%p\n",x);
printf("%p\n",y);
printf("%p\n",z);
x++;
y++;
z++;
printf("%p\n",x);
printf("%p\n",y);
printf("%p\n",z);
Printing them out in this way will print their addresses, and you should see their address change after you increment them.
However, if you attempt to access the values stored in them after you increment them, you'll either get garbage or your program will crash. When you increment the value of a pointer like that, it will point to the next location in memory. When the pointer points to an array it will point to the array's next cell. However, your pointers do not point to an array, so the address they point to will probably not be valid.

Related

Increment a pointer and value store in it

#include <stdio.h>
int main()
{
int N = 4;
int *ptr1;
// Pointer stores
// the address of N
ptr1 = &N;
printf("Value #Pointer ptr1 before Increment: ");
printf("%d \n", *ptr1);
// Incrementing pointer ptr1;
ptr1++;
*ptr1=5;
printf("Value #Pointer ptr1 after Increment: ");
printf("%d \n\n", *ptr1);
return 0;
}
The output I was expecting is that printf prints the value 4 and then the value 5.
But after executing the 1st printf statement the code exited and the code never printed the 2nd printf.
Can anyone please explain what am I doing wrong?
As per my knowledge I am incrementing a pointer then storing a new value into the incremented address.
Have I understood it right?
Welcome to stackoverflow :D
The problem is that you have allocated space for a single integer. But you're trying to access two integers. Which is undefined behavior; meaning that sometimes it will crash, like in your case, and sometimes it might work, and some other times it might work but give unpredictable results.
When you increment the pointer you go to an address in memory that you have not allocated. If you want two integers, maybe allocate an array like this:
int N[2] = {4, 4};
Now when you increment the address of the pointer, you're reaching valid memory that you have allocated.
You're incrementing the pointer.
But it looks like you want to increment the value that the pointer points to.
Try this:
(*ptr1)++;
The parentheses are important: they say that what you're incrementing is the contents of the pointer pointed to --
that is, what the ++ operator is applied to is the subexpression (*ptr1).
See also Question 4.3 in the C FAQ list.
When you try to increment a pointer, what c does is this: "ptr + 1 * sizeof(int)" (assuming that ptr is an int pointer). So, now, it is pointing 4 bytes ahead of the variable "N"(assuming that you are on a 64 bit machine) which probably is occupied by another program. When you dereference it you are taking the value that is stored 4 bytes ahead of "N". With that being said, I recommend this:
(*ptr)++

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”.

How do I use pointers? in C

Im fairly new to C programming and I am confused as to how pointers work. How do you use ONLY pointers to copy values for example ... use only pointers to copy the value in x into y.
#include <stdio.h>
int main (void)
{
int x,y;
int *ptr1;
ptr1 = &x;
printf("Input a number: \n");
scanf("%d",&x);
y = ptr1;
printf("Y : %d \n",y);
return 0;
}
It is quite simple. & returns the address of a variable. So when you do:
ptr1 = &x;
ptr1 is pointing to x, or holding variable x's address.
Now lets say you want to copy the value from the variable ptr1 is pointing to. You need to use *. When you write
y = ptr1;
the value of ptr1 is in y, not the value ptr1 was pointing to. To put the value of the variable, ptr1 is pointing to, use *:
y = *ptr1;
This will put the value of the variable ptr1 was pointing to in y, or in simple terms, put the value of x in y. This is because ptr1 is pointing to x.
To solve simple issues like this next time, enable all warnings and errors of your compiler, during compilation.
If you're using gcc, use -Wall and -Wextra. -Wall will enable all warnings and -Wextra will turn all warnings into errors, confirming that you do not ignore the warnings.
What's a pointer??
A pointer is a special primitive-type in C. As well as the int type stored decimals, a pointer stored memory address.
How to create pointers
For all types and user-types (i.e. structures, unions) you must do:
Type * pointer_name;
int * pointer_to_int;
MyStruct * pointer_to_myStruct;
How to assing pointers
As I said, i pointer stored memory address, so the & operator returns the memory address of a variable.
int a = 26;
int *pointer1 = &a, *pointer2, *pointer3; // pointer1 points to a
pointer2 = &a; // pointer2 points to a
pointer3 = pointer2; // pointer3 points to the memory address that pointer2 too points, so pointer3 points to a :)
How to use a pointer value
If you want to access to the value of a pointer you must to use the * operator:
int y = *pointer1; // Ok, y = a. So y = 25 ;)
int y = pointer1; // Error, y can't store memory address.
Editing value of a variable points by a pointer
To change the value of a variable through a pointer, first, you must to access to the value and then change it.
*pointer1++; // Ok, a = 27;
*pointer1 = 12; // Ok, a = 12;
pointer1 = 12; // Noo, pointer1 points to the memory address 12. It's a problem and maybe it does crush your program.
pointer1++; // Only when you use pointer and arrays ;).
Long Winded Explanation of Pointers
When explaining what pointers are to people who already know how to program, I find that it's really easy to introduce them using array terminology.
Below all abstraction, your computer's memory is really just a big array, which we will call mem. mem[0] is the first byte in memory, mem[1] is the second, and so forth.
When your program is running, almost all variables are stored in memory somewhere. The way variables are seen in code is pretty simple. Your CPU knows a number which is an index in mem (which I'll call base) where your program's data is, and the actual code just refers to variables using base and an offset.
For a hypothetical bit of code, let's look at this:
byte foo(byte a, byte b){
byte c = a + b;
return c;
}
A naive but good example of what this actually ends up looking like after compiling is something along the lines of:
Move base to make room for three new bytes
Set mem[base+0] (variable a) to the value of a
Set mem[base+1] (variable b) to the value of b
Set mem[base+2] (variable c) to the sum mem[base+0] + mem[base+1]
Set the return value to mem[base+2]
Move base back to where it was before calling the function
The exact details of what happens is platform and convention specific, but will generally look like that without any optimizations.
As the example illustrates, the notion of a b and c being special entities kind of goes out the window. The compiler calculates what offset to give the variables when generating relevant code, but the end result just deals with base and hard-coded offsets.
What is a pointer?
A pointer is just a fancy way to refer to an index within the mem array. In fact, a pointer is really just a number. That's all it is; C just gives you some syntax to make it a little more obvious that it's supposed to be an index in the mem array rather than some arbitrary number.
What a does referencing and dereferencing mean?
When you reference a variable (like &var) the compiler retrieves the offset it calculated for the variable, and then emits some code that roughly means "Return the sum of base and the variable's offset"
Here's another bit of code:
void foo(byte a){
byte bar = a;
byte *ptr = &bar;
}
(Yes, it doesn't do anything, but it's for illustration of basic concepts)
This roughly translates to:
Move base to make room for two bytes and a pointer
Set mem[base+0] (variable a) to the value of a
Set mem[base+1] (variable bar) to the value of mem[base+0]
Set mem[base+2] (variable ptr) to the value of base+1 (since 1 was the offset used for bar)
Move base back to where it had been earlier
In this example you can see that when you reference a variable, the compiler just uses the memory index as the value, rather than the value found in mem at that index.
Now, when you dereference a pointer (like *ptr) the compiler uses the value stored in the pointer as the index in mem. Example:
void foo(byte* a){
byte value = *a;
}
Explanation:
Move base to make room for a pointer and a byte
Set mem[base+0] (variable a) to the value of a
Set mem[base+1] (variable value) to mem[mem[base+0]]
Move base back to where it started
In this example, the compiler uses the value in memory where the index of that value is specified by another value in memory. This can go as deep as you want, but usually only ever goes one or two levels deep.
A few notes
Since referenced variables are really just numbers, you can't reference a reference or assign a value to a reference, since base+offset is the value we get from the first reference, which is not stored in memory, and thus we cannot get the location where that is stored in memory. (&var = value; and &&var are illegal statements). However, you can dereference a reference, but that just puts you back where you started (*&var is legal).
On the flipside, since a dereferenced variable is a value in memory, you can reference a dereferenced value, dereference a dereferenced value, and assign data to a dereferenced variable. (*var = value;, &*var, and **var are all legal statements.)
Also, not all types are one byte large, but I simplified the examples to make it a bit more easy to grasp. In reality, a pointer would occupy several bytes in memory on most machines, but I kept it at one byte to avoid confusing the issue. The general principle is the same.
Summed up
Memory is just a big array I'm calling mem.
Each variable is stored in memory at a location I'm calling varlocation which is specified by the compiler for every variable.
When the computer refers to a variable normally, it ends up looking like mem[varlocation] in the end code.
When you reference the variable, you just get the numerical value of varlocation in the end code.
When you dereference the variable, you get the value of mem[mem[varlocation]] in the code.
tl;dr - To actually answer the question...
//Your variables x and y and ptr
int x, y;
int *ptr;
//Store the location of x (x_location) in the ptr variable
ptr = &x; //Roughly: mem[ptr_location] = x_location;
//Initialize your x value with scanf
//Notice scanf takes the location of (a.k.a. pointer to) x to know where
//to put the value in memory
scanf("%d", &x);
y = *ptr; //Roughly: mem[y_location] = mem[mem[ptr_location]]
//Since 'mem[ptr_location]' was set to the value 'x_location',
//then that line turns into 'mem[y_location] = mem[x_location]'
//which is the same thing as 'y = x;'
Overall, you just missed the star to dereference the variable, as others have already pointed out.
Simply change y = ptr1; to y = *ptr1;.
This is because ptr1 is a pointer to x, and to get the value of x, you have to dereference ptr1 by adding a leading *.

Why can't a c pointer be treated as an array?

In the question Find size of array without using sizeof in C the asker treats an int array like an array of int arrays by taking the address and then specifying an array index of 1:
int arr[100];
printf ("%d\n", (&arr)[1] - arr);
The value ends up being the address of the first element in the "next" array of 100 elements after arr. When I try this similar code it doesn't seem to do the same thing:
int *y = NULL;
printf("y = %d\n", y);
printf("(&y)[0] = %d\n", (&y)[0]);
printf("(&y)[1] = %d\n", (&y)[1]);
I end up getting:
y = 1552652636
(&y)[0] = 1552652636
(&y)[1] = 0
Why isn't (&y)[1] the address of the "next" pointer to an int after y?
Here:
printf("(&y)[1] = %d\n", (&y)[1]);
You say first: take address of y. Then afterwards you say: add 1 times so many bytes as the size of the thing which is pointed to - which is pointer to int, and hence probably 4 bytes are added - and dereference whatever is that on that address. But you don't know what is on that new memory address and you can't/shouldn't access that.
Arrays are not pointers, and pointers are not arrays.
The "array size" code calculates the distance between two arrays, which will be the size of an array.
Your code attempts to calculate the distance between two pointers, which should be the size of a pointer.
I believe the source of confusion is that (&y)[1] is the value of the "next" pointer to an int after y, not its address.
Its address is &y + 1.
In the same way, the address of y is &y, and (&y)[0] - or, equivalently *(&y) - is y's value.
(In the "array size" code, (&arr)[1] is also the "next" value, but since this value is an array, it gets implicitly converted to a pointer to the array's first element — &((&array)[1])[0].)
If you run this:
int *y = NULL;
printf("y = %p\n", y);
printf("&y = %p\n", &y + 0);
printf("&y + 1 = %p\n", &y + 1);
the output looks somewhat like this:
y = (nil)
&y = 0xbf86718c
&y + 1 = 0xbf867190
and 0xbf867190 - 0xbf86718c = 4, which makes sense with 32-bit pointers.
Accessing (&y)[1] (i.e. *(&y + 1)) is undefined and probably results in some random garbage.
Thanks for the answers, I think the simplest way to answer the question is to understand what the value of each expression is. First we must know the type, then we can determine the value
I used the c compiler to generate a warning by assigning the values to the wrong type (a char) so I could see exactly what it thinks the types are.
Given the declaration int arr[100], the type of (&arr)[1] is int [100].
Given the declaration int *ptr, the type of (&ptr)[1] is int *.
The value of a int[100] is the constant memory address of where the array starts. I don't know all the history of why that is exactly.
The value of a int * on the other hand is whatever memory address that pointer happens to be holding at the time.
So they are very different things. To get the constant memory address of where a pointer starts you must dereference it. So &(&ptr)[1] is int ** which the constant memory address of where the int pointer starts.

What is the difference between *x=i and x=&i

What is the difference between *x=i and x=&i?
Code:
int i=2;
int *x;
*x=i; //what is the difference between this...
x=&i; //...and this??
//Also, what happens when I do these? Not really important but curious.
x=i;
*x=*i;
*x=i; //what is the difference between this...
This assigns the value of i to an integer stored at the address pointed to by x
x=&i; //...and this??
This assigns the address of i to x.
Note that in your example x is unassigned, so the behavior of *x=i is undefined.
Here is a better illustration:
int i = 2, j = 5;
printf("%d %d\n", i, j); // Prints 2 5
int *x = &j;
*x = i;
printf("%d %d\n", i, j); // Prints 2 2
int i=2;
int *x;
*x=i; // x is not initialized, this is undefined behavior
x=&i; // this assigns the address of i to x
and
*x=&i; // is invalid C. You cannot assign a pointer to an
// integer without an explicit conversion.
*x=i changes the value stored in the memory location pointed to by x to be equal to the value stored in i.
x=&i changes the memory location x is pointing to to i's memory location.
x=i is wrong. You will most likely get a segfault.
*x=*i is wrong. You cannot dereference i, because i is not a pointer.
*x=&i (actually, more properly, *x=(int)&i) will store the memory location of i as an integer in the memory location pointed to by x.
*x=i; dereferences the pointer x and assigns i.
x=&i makes the pointer x point at the variable i.
*x = i changes the value stored at the address which is stored in x. In your case, unedited, that will crash, because the address x is likely junk, possibly NULL. You would need a malloc() or new or something.
x = &i changes the address stored in x, so that is is the address of the variable i. This is perfectly safe in your example.
Well, when you say
*x = i
You're saying: make the variable x points to the value i.
When you say
x = &i
You're saying make the address x points to the address of i.
And I guess you should be able to figure the other ones out by yourself!
*x = i
This actually assigns the value of i to the memory location pointed to by x.
x = &i
This assigns the address of variable i to a pointer variable x. x should be a pointer.
When you do x = i, this will give you a runtime error, as you are trying to erroneously assign an address(which in this case is 2) which does not belong to the address space of your process. To successfully do this, i should also be a pointer and must point to an address which is in your address space.
When you do *x = *i, in your case will again give an error. If i is a pointer, then the address pointed to by x will get the value present at the address pointed to by i.
*x = i assigns 2 to the memory address pointed to by x. Note that this would probably crash because x hasn't been initialized to a memory address via malloc or an assignment to a buffer or address of a stack variable.
x = &i assigns the pointer x to the address of variable i.
x = i would assign the pointer x to the value of 2, which would most likely point to an invalid memory address and would require a cast.
*x = *i would depend on the current value of x. And since i is not a pointer you cannot dereference it.
*x = &i would write the address of i to the memory address pointed to by x, which would depend on the code preceding it. It would likely crash if you didn't assign x to a valid address.
Some of these calls would require a cast to be syntactically correct.

Resources