I have some issues getting my head around the idea of pointers. I know what they do in theory, but i have a problem understanding what they can actually be capable of. The basic exercises that i have seen are a bit vague in my opinion because they can be done without the actual subject. For example swapping two number, either by reference or by address.
#include <iostream>
using namespace std;
int main()
{
int a = 45, b = 35;
cout << "Before Swap\n";
cout << "a = " << a << " b = " << b << "\n";
int z = a;
a = b;
b = z;
cout << "After Swap with pass by reference\n";
cout << "a = " << a << " b = " << b << "\n";
}
//copied an example i saw online with pointers and modified it to get the
same result without needing them
One example on when using pointers could be better (assuming this is some sort of school context) would be if you want to make a function to swap the numbers instead of rewriting your code a lot.
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
return
}
If you tried using integers in the function instead of pointers, it'd swap the values locally, and not swap the variables in a greater context. What you could do to achieve the same results is use references instead (ie int &a, int &b), so you don't really need to use pointers, and in this example they aren't particularly useful.
Pragmatically, std::swap()is much more useful in modern c++, but the example above might be why the online tutorial uses pointers.
Pointers can be useful in other contexts, but I don't know if that's within the scope of your question, just perhaps what the tutorial was trying to achieve by using pointers.
Use the std::swap() method for swaping.
It is more efficient.
For your understanding if we write a function which swaps two values
so we have to pass the values by reference and not by value.
same is
the case with pointers.some time we need to swap value by pointers.
So if we pass values to this function from the main it will swap it.
void swap(int&,int&);
But here it won't work if we pass values to this function from the main.
void swap(int,int);
Related
As a beginner in C++, first thing I came accross for functions is that they use a copy of the argument, for example if we execute this :
void add (double x){
x=x+3;
}
int main(){
double x=2 ;
add(x) ;
}
Then x would actually be equal to 2, not 5. Later on, learning about pointers, I found the following :
void fill (int *t){
for (int j=0, j<10, j++){
t[j]=j;
}
int main(){
int* p;
p = new int[10];
fill(p);
}
Now if we print what p contains, we find that it's indeed filled by the integers. I have some trouble understanding why it does that as I feel like it should have been the same as the first function ?
Thanks.
The reason it isn't the same as the first function is because you are passing the pointer by value. This means that if you modify the actual pointer, e.g by assigning to it, then it would only be in that state inside the function. The value that the pointer points to is still the original value, which will get modified since both copied pointers point to that same original value (don't forget notation of the form a[i] is equivalent to *(a + i), which does a dereference and is modifying the pointed value, not the pointer itself).
A small example that illustrates this would be the following (not accounting for memory leaks):
#include <iostream>
int test(int* x)
{
int* y = new int{10};
x = y;
std::cout << "Inside function: " << *x << "\n";
}
int main()
{
int* t = new int{5};
std::cout << "Before function: " << *t << "\n";
test(t);
std::cout << "After function: " << *t << "\n";
}
In first example you are using ordinary variable. When passing normal variable to function, like this, the function creates its own copy of the variable (it has same value as it has when you passed it, but it was copied to different place in memory). That is standard behaviour.
In second example you are using pointer: we can say that it points to the place in memory, where values are stored. Few of the advantages of them:
1) If you want to spare memory, but need to use same value in different functions -> mostly appplies to bigger objects than double, like array in your example
2) If you need to change value of variable/array/object in different functions
But careful, in the second function you still created copy, but not of value, but pointer. So basically, the "new" pointer is different object, but it is pointing to the same place in memory, so when accessing the value (which you are doing with [j]), you are editing the same place in memory.
It is not that easy concept to grasp, especially with more dimentional arrays, but hope this helped a little. You can learn some more in tutorials or c++ docs, for example this is a good one: https://www.geeksforgeeks.org/pointers-in-c-and-c-set-1-introduction-arithmetic-and-array/
I was trying to access the private data members of the class. Everything was going fine until I came upon the int*. I don’t get what it is. I think it’s something that we can use to create a new memory address.
My code :
#include <iostream>
using namespace std;
class x
{
int a, b, c, d;
public:
x()
{
a = 100;
b = 200;
c = 300;
d = 400;
}
};
int main()
{
x ob;
int *y = (int *)&ob;
cout << *y << " " << y[1] << " " << y[2] << " " << y[3] << endl;
}
Can anyone help me in understanding it?
Its a c-style cast to access the memory occupied by the struct x as a set of ints.
It takes the address of ob, casts it from 'address of' (ie a pointer to) x into a pointer to int. The compiler happily assigns this cast to y, so you can manipulate it, or in this case, print out the memory blocks as ints. As the struct happens to be a group of ints anyway, it all works even though its a bit of a hack. I guess the original coder wanted to print out all 4 ints without having to specify each one in turn by variable name. Lazy.
Try using a cast to a char* (ie 1 byte at a time) and print those out. You'll be basically printing out the raw memory occupied by the struct.
A good C++ way would be to create an operator<< function that returns each variable formatted for output like this, then write cout << ob << endl; instead.
Consider the trivial test of this swap function in C++ which uses pass by pointer.
#include <iostream>
using std::cout;
using std::endl;
void swap_ints(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
return;
}
int main(void)
{
int a = 1;
int b = 0;
cout << "a = " << a << "\t" << "b = " << b << "\n\n";
swap_ints(&a, &b);
cout << "a = " << a << "\t" << "b = " << b << endl;
return 0;
}
Does this program use more memory than if I had passed by address? Such as in this function decleration:
void swap_ints(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
return;
}
Does this pass-by-reference version of the C++ function use less memory, by not needing to create the pointer variables?
And does C not have this "pass-by-reference" ability the same that C++ does? If so, then why not, because it means more memory efficient code right? If not, what is the pitfall behind this that C does not adopt this ability. I suppose what I am not consider is the fact that C++ probably creates pointers to achieve this functionality behind the scenes. Is this what the compiler actually does -- and so C++ really does not have any true advantage besides neater code?
The only way to be sure would be to examine the code the compiler generated for each and compare the two to see what you get.
That said, I'd be a bit surprised to see a real difference (at least when optimization was enabled), at least for a reasonably mainstream compiler. You might see a difference for a compiler on some really tiny embedded system that hasn't been updated in the last decade or so, but even there it's honestly pretty unlikely.
I should also add that in most cases I'd expect to see code for such a trivial function generated inline, so there was on function call or parameter passing involved at all. In a typical case, it's likely to come down to nothing more than a couple of loads and stores.
Don't confuse counting variables in your code with counting memory used by the processor. C++ has many abstractions that hide the inner workings of the compiler in order to make things simpler and easier for a human to follow.
By design, C does not have quite as many levels of abstractions as C++.
I have the following sample code. Just wanted to know if is valid to take address of a local variable in a global pointer and then modify it's contents in a sub function. Following program correctly modifies value of variable a . Can such practice cause any issues ?
#include <iostream>
#include <vector>
using namespace std;
vector<int*> va;
void func()
{
int b ;
b = 10;
int * c = va[0];
cout << "VALUE OF C=" << *c << endl;
*c = 20;
cout << "VALUE OF C=" << *c << endl;
}
int main()
{
int a;
a = 1;
va.push_back(&a);
func();
cout << "VALUE IS= " << a << endl;
return 0;
}
This is OK, as long as you don't try to dereference va[0] after a has gone out of scope. You don't, so technically this code is fine.
That said, this whole approach may not be such a good idea because it makes code very hard to maintain.
I'd say that if your program grows you could forget about a change you made in some function and get some weird errors you didn't expect.
Your code is perfectly valid as long as you call func() while being in the scope of a. However, this is not considered to be a good practice. Consider
struct HugeStruct {
int a;
};
std::vector<HugeStruct*> va;
void print_va()
{
for (size_t i = 0; i < va.size(); i++)
std::cout<<va[i].a<<' ';
std::cout<<std:endl;
}
int main()
{
for (int i = 0; i < 4; i++) {
HugeStruct hs = {i};
va.push_back(&hs);
}
print_va(); // oups ...
}
There are 2 problems in the code above.
Don't use global variables unless absolutely necessary. Global variables violate encapsulation and may cause overlay of variable names. In most cases it's much easier to pass them to functions when needed.
The vector of pointers in this code looks awful. As you can see, I forgot that pointers became invalid as soon as I left for-loop, and print_va just printed out garbage. The simple solution could be to store objects in a vector instead of pointers. But what if I don't want HugeStruct objects to be copied again and again? It can take quite a lot of time. (Suppose that instead of one int we have a vector of million integers.) One of the solutions is to allocate HugeStructs dynamically and use vector of smart pointers: std::vector<std::shared_ptr<HugeStruct>>. This way you don't have to bother about memory management and scope. Objects will be destroyed as soon as nobody will refer to them.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Pointer vs. Reference
Hi All,
I was trying to explore and I encountered a concern with the reference operator. Consider a normal call by reference swap code as below, which works as desired
#include<iostream>
using namespace std;
void test(int *a,int *b){
int temp;
temp = *a;
*a= *b;
*b= temp;
cout<<"\n Func a="<<*a << " b=" << *b;
}
int main()
{
int a=5,b =3;
cout<<"\n Main a="<<a << " b=" << b;
test(&a,&b);
cout<<"\n Main again a="<<a << " b=" << b;
return 0;
}
On the other hand a code as below also does the same kind of swapping and yield exactly the same result.
#include<iostream>
using namespace std;
void test(int &a,int &b){
int temp;
temp = a;
a= b;
b= temp;
cout<<"\n Func a="<<a << " b=" << b;
}
int main()
{
int a=5,b =3;
cout<<"\n Main a="<<a << " b=" << b;
test(a,b);
cout<<"\n Main again a="<<a << " b=" << b;
return 0;
}
Can some one explain how different is the function call in the second example(first part I am comfortable in which the address is taken as the reference, but what happens in the second case) ?
Within the same line, hope the same happens in an assignment statement as well i.e.
int a=5;
int &b=a;
Thanks in advance.
EDIT:
Thanks for the replies. But my doubt is what exactly happens in the memory
int *pointer=&x
stores the address but what happens when we do
int &point=x.
Both versions perform an identical job and quite probably the compiler will emit identical object code.
The version using reference parameters is much easier to read.
You can pass a NULL pointer to the version that uses pointers which leads to a memory violation. The same mistake cannot be made with reference parameters.
& means that you're passing your parameter by reference. The variable you've passed is exactly the same variable you're operating in your function. Actually there is no significant difference between using pointer or reference, because when you passing pointer and then dereference it, you again get exactly the same variable. To sum up: in both cases it's possible to modify passed variable. The opposite, when you pass variables value.
In both cases you are passing the variables by reference. In the first function you can conceptually think of the address that is being passed. In the second example though, I conceptually think of the variable itself being passed, but passed by reference instead of by value.
I am not 100% sure, but I suspect on most compilers they would compile to the same object code.