#include <stdlib.h>
int main(void)
{
int* x;
int* y;
x = malloc(sizeof(int));
*x = 42;
*y = 13;
y = x;
return 0;
}
Where is the Error in which line and why.. ? Can't I assign pointer to another pointer. Yes nothing is being printed out in this .. Actually its my homework question...
You need to allocate memory for y before assigning value to it.
y = malloc(sizeof(int));
*y = 13
The error is here: *y = 13; The problem is that y has not been previously assigned (i.e. an undefined behavior).
Switching
*y = 13;
y = x;
to
y = x;
*y = 13;
fixes the problem. Obviously, the memory leak of malloc(sizeof(int)) still remains.
y is a wild pointer, you are assigning 13 to nothing. You need to malloc() it, too.
Either use malloc like
y = malloc(sizeof(int));
*y = 13;
or make y a stack-variable like
int y = 0;
...
y = *x; //copy value from x to y by dereferencing x
When you use pointers,you have to understand one thing : You are not actually allocating memory in the stack,you just create a pointer to something.That something can be anything but we don't really care. We just have to initialize it and we do that by making it point to something.
There are two ways,the first one is to make it point to a stack variable and the second to make it point to place in the stack,that you allocated using malloc().
The first way:
int x; //you create a stack variable
int *ptr; //you create a type int pointer
ptr=&x; //you make ptr point to the adress where 'x' is
The second way:
int *ptr; //you create a type int pointer
*ptr=malloc(sizeof(int)); you allocate memory for one int
The problem with you code above is that you haven't allocated memory for int *y and yet you try to save a number there.
Your code could be written like that
#include <stdlib.h>
int main(void)
{
int* x;
int* y;
x = malloc(sizeof(int));
y = malloc(sizeof(int));
//now both pointers point to a place in memory so you can actually save data on them
*x = 42;
*y = 13;
y = x;
return 0;
}
The problem of cource here is that when you make y point to x ,you lose the place y was pointing and you leave non usable allocating place in the memory.So before making y point to x you could use free().
*y=13;
free(y);
y=x;
Related
In the following code I would like to understand better what is happening with int *z = malloc(sizeof(int);
To me that creates a pointer to an int. Then *z gets the sum of the value that x points to (2) and the value that y points to (4).
Now *z = 6. Does that mean *z does not point to anything? It just stores an int? I thought *z was a pointer and a pointer is an address? Thank you for any help understanding.
int *add(int *x, int *y)
{
int *z = malloc(sizeof(int));
*z = (*x) + (*y);
return z;
}
int main(void)
{
int a = 2;
int b = 4;
int *ptr = add(&a, &b);
printf("sum = %i\n", *ptr);
}
Now *z = 6. Does that mean *z does not point to anything? It just stores an int? I thought *z was a pointer and a pointer is an address? Thank you for any help understanding.
You are correct with *z = 6 however you are wrong with how this happens.
z is a pointer and so it point somewhere into the memory. Earlier in your program, with int *z = malloc(sizeof(int)); you have allocated a space the z points to.
Then when you did *z = (*x) + (*y); you've basically put the result of the addition into that allocated space.
z still points to that space (because it is a pointer). *z is called dereferencing and has a meaning of reaching directly for the value the pointer points to.
In other words: the 6 is stored in a place the z points to and *z is a way to grab that value.
*z = 6 assigns 6 to the location pointed at by ptr. That's what a pointer does, it points to things, but in order to put a value at where it's pointing as opposed to changing the pointer you need to de-reference with the * operator.1
Imagine your memory as, conceptually, a number of bytes each of which has a number. A pointer to an int represents a particular location in memory which is presumed to hold an int, or 4 bytes worth of data.
*z = 6 means "put an integer value of 6 in the memory location described by z", which translates into machine instructions that are largely the same.
z absolutely does not "store an int", it stores a location. That location may exist, or may be NULL, or may be invalid. There's no guarantees unless you've checked your code carefully to ensure the pointer is valid. That's your responsibility as a programmer.
That's also why pointers can be tricky and frustrating. They introduce indirection in your code.
1 In C pointers are also largely interchangeable with arrays so you can do z[0] = 6, though as z only points to a single int, any index other than 0 is invalid.
int *z = malloc(sizeof(int));
this will envoke a system call for allocating one integer on the heap. z is the address of this integer return from malloc (if malloc fails to allocate z will be null)
z is a pointer to buffer allocated on the heap (if malloc success). in your case this buffer hold one integer so its a pointer to this integer.
see malloc description in man pages. malloc_man_pages
*z = (*x) + (*y);
you are right. you are assigning the value that sets in the address x and the value that sets in the address y to the place that z points to.
you dont check the return vale from malloc and this is a very bad thing. always check if malloc successd! see below. maybe you need to check the pointers that you get in x and y ?! (thats up to you, but i recommend to check).
int* add(int *x, int *y)
{
int *z = NULL;
if(x && y)
{
z = malloc(sizeof(int));
if(z)
{
*z = (*x) + (*y);
}
}
return z;
}
The question surely look stupid, but I have always wasted a lot of time, with tests/errors until it works, with this kind of problem.
I need a pointer to return a value from a function, then I need to divide this value, but I have the compiler error:
invalid operands to binary / (have 'int *' and 'int')
Example in the following code:
void test(int *x, int y)
{
*x = *x+y;
}
int main()
{
int *x = 20;
int y = 1;
test(&x, y);
printf("x: %i", x);
float res = x / 2; // error: invalid operands to binary / (have 'int *' and 'int')
//float res = *x / 2; // application crash with this one. (GCC native Android)
}
I tried with '&' but it didn't work (x = 0), I try cast to int and only get the pointer adress, etc.
Your immediate problem is that you have declared x as a pointer to int, but you are trying to use it as an int. To simply correct the last line, dereference the pointer (just like you've correctly done inside test()):
float res = *x / 2;
Now, it appears you actually tried that and got an error, which is not surprising, because you've initialized x badly:
int *x = 20;
This doesn't create an int value of 20 and make x point to it. It sets x to point at the memory address represented by the integer value 20. That's probably reserved memory, which is why you get an error when you try to dereference it.
(You don't get that error in test() because you've passed the address of x as the argument. So dereferencing it there actually does get you 20 - probably.)
To make the pointers work, either do:
int x = 20;
...
test(&x, y)
...
float res = x / 2;
or:
int *x = malloc(sizeof(int));
*x = 20;
...
test(x, y)
..
float res = *x /2;
But you are really making this too difficult. Since you only need to output one value from the function, just make the function return that value. Then you have no need to mess about with pointers at all:
int test(x,y) { return x+y; }
...
int x = 20;
...
x = test(x,y);
...
float res = x / 2;
(And finally, I believe that in any case you want to use 2.0 in the last line, not just 2, if you want to get a float result instead of an int.)
int * x = 20; means: x is a pointer to an int stored at address 20. When you deference it, the CPU will try to read an int value from address 20, yet address 20 is an invalid address in your current process space and thus your program crashes.
What you probably wanted do say is: x is a pointer to an int and the value of the int it points to is 20, correct? Well, this would have been:
int someInt = 20;
int * x = &someInt;
Now x points to whatever address someInt stores its value (actually it's on the stack space of the main function, but that's just a side node) and the value stored at that address is in fact 20.
I am very new to C and currently having some trouble with pointers and I am not sure if my logic is correct on this question clarification would be great.
Is the second expression legal? Why or Why not? What does it mean?
int** x = ....;
... **x ...
This is all the question gives and I came up with the following answer (I think its in the ballpark)
The int** x will initialize a pointer x to whatever address/value that is after the equal sign.
**x ... will dereference the pointer to a value/variable
The question link that was proposed in the edit was just showing the difference between int* p and int *p which is nothing what i asked i understand this already.
int *x is a pointer to int. int** y defines y as a pointer to pointer to int, so it points to a pointer, and the latter points to an int. Example:
int n = 42;
int* x = &n; // points to n
int** y = &x; // points to x, which points to n
In this case y is a pointer to pointer. First indirection *y gives you a pointer (in this case x), then the second indirection dereferences the pointer x, so **y equals 42.
Using typedefs makes everything looks simpler, and makes you realize that pointers are themselves variables as any other variables, the only exception being that they store addresses instead of numbers(values):
typedef int* pINT;
int n = 42;
pINT x = &n;
pINT* y = &x; // y is a pointer to a type pINT, i.e. pointer to pointer to int
If you use double * you are telling the compiler you want a pointer pointing to another pointer:
int x = 4;
int *pointer = &x;
int **pointer_pointer = &pointer;
printf("%d\n",**pointer_pointer); // This should print the 4
Program:
int x;
int *y;
int **z;
z = (int **) malloc (sizeof(int *));
y = (int *) malloc (sizeof(int));
x = 1;
*z = &x;
*y = x;
.
.
.
Question:
What is the difference between:
*z = &x;
*y = x;
From what I understand *z points to the address of x and *y points to x, but for *y to point to x doesn't that require the address of x? I don't really understand what's going on with these two variables.
Edit:
I also want to know when do we know when a variable is allocated on the stack or on the heap?
Why is x,y, and z allocated on the stack?
Why is *y, **y, *z, **z, allocated on the heap?
Finally, does changing *z, change **z?
z is a pointer to a pointer (which will typically point to a dynamically allocated array of pointers).
y is a pointer to int. Again, more often than not it'll point to a dynamically allocated array of ints.
So, the *z = &x; is setting the pointer that z refers to to point at x. I.e., z points at a pointer, which (in turn) points to x.
*y = x; is taking the value of x and assigning it to the int pointed to by y.
For things like this, a picture is often helpful. So, our basic definitions give us this:
The we do:
z = (int **) malloc (sizeof(int *));
y = (int *) malloc (sizeof(int));
Which gives us this:
Then we do:
*z = &x;
*y = x;
Which gives us this:
In all of these, a dashed line signifies a pointer from one place to another, while the solid line indicates copying a value from one place to another.
We can then consider the long-term differences between them. For example, consider what happens if we add x=2; after all the assignments above.
In this case, *y will still equal 1, because we copied the value 1 from x to *y. **z will equal 2 though, because it's just a pointer to x -- any change in x will be reflected in **z.
This line stores the address of variable x in the memory pointed to by z:
*z = &x;
This line stores the value of x into memory pointed to by y:
*y = x;
The two assignment statements are unrelated: the second one makes a copy, while the first one does not. If you change the value of x and then retrieve **z, you will see the new value of x; however, retrieving *y would give you back the old value of x (i.e. 1).
I'm a bit confused as to why the following code crashes:
int main(){
int *a;
int *b;
*a = -2;
*b = 5; //This line causes a crash on my system.
return 0;
}
Shouldn't memory automatically be allocated for two pointers and two integers before run-time because of the declarations?
Or must you always explicitly allocate memory?
No. You've only declared the pointers, not what they point to. The pointers are allocated on the stack, and since you've not initialized them to anything, their values are garbage.
int main() {
int a = 7;
int *p_a; // p_a contains whatever garbage was on the stack at its
// location when main() is called. (Effectively points nowhere).
p_a = &a; // p_a points to (gets the address of) variable a, also on
// the stack.
printf("Before: a = %d\n", a); // prints 7
*p_a = -2;
printf("After: a = %d\n", a); // prints -2
return 0;
}
I would code up the above example, and step through it in a debugger. You'll see what I mean about what p_a is pointing to.
Shouldn't memory automatically be allocated for two pointers and two integers before run-time because of the declarations?
I only see you specifying two pointers. Where are the two integers?
Or must you always explicitly allocate memory?
Pointers have to point to something. Either local variables on the stack, or malloc'd memory from the heap.
In this code:
int* a;
*a = -2;
a is an uninitialized pointer, dereferencing of which produces undefined behavior, that you were luckily able to observe as a crash of your application.
You need to initialize the pointer (make it point to the valid memory) before you dereference it (i.e. before you use *, the dereference operator):
int a;
int* pA = &a;
*pA = -2;
Consider
int m;
int n;
m = n;
This is invalid because you're trying to use n but you haven't assigned a value to it. Now:
int *a;
*a = -2;
Likewise, this is invalid because you're trying to use a but you haven't assigned a value to it. The value of a is not an int, it's a pointer to int. For example,
int someint;
a = &someint;
*a = -2;
puts -2 into someint. Without the assignment to a, the place to put -2 is undeterminable. Also,
a = malloc(sizeof(int));
*a = -2;
Here, a is given the value of the address of some location in the heap; -2 goes into that heap location.
Perhaps an analogy would be helpful:
Consider the phrase "her dog". This is a reference to someone's' dog, but it won't do to tell me "give her dog a bone" if you haven't told me who she is. Similarly, "pointer to an int" doesn't tell the system which int it is.
Your *a and *b pointers are not initializated properly.
Try this one:
int my_a;
int my_b;
int *a;
int *b;
a = &my_a; // init the pointer a to the direction of my_a int variable
b = &my_b;
*a = 3; // set the my_a value via pointer
*b = 2;
You have just declared pointers but you haven't initialized them. So, you can't be sure that *b = 5 is causing the program to crash. It could be *a = -2 as well. To fix it, you should initialize your pointers as well.
int aval = -2;
int bval = 5;
int *a = &aval; // declared and initialized pointers
int *b = &bval;
// Now you can change the value using the pointer
*a = 15;
*b = 20;