I have the following code:
#include <iostream>
using namespace std;
int main ()
{
int myvar = 5;
int * p;
cout << "Hello2" << endl;
*p = myvar;
cout << "Hello" << endl;
cout << p << endl;
//cout << &myvar << endl;
}
I know I am not doing the right thing by not initializing the pointer. I was just playing with pointers and noticed this. The issue is when I comment out the last line, the program executes normally. But as soon as I uncomment the line, I get a segmentation fault. I don't know why printing address of myvar is causing this? Has myvar been modified in any way because of pointer dereferencing? I am using C++11.
int* p;
*p = myvar;
You are creating an uninitialized pointer and then derferencing that pointer. This has undefined behavior because p has to point to something for it to be derferenced correctly. Therefore your program's behavior can't be reasoned with.
Segmentation Fault occurs when trying to access a virtual memory address that has no read permissions.
In your case, the local variable p holds uninitialized garbage from the stack.
you are dereferencing a memory address that might not be readable(e.g no read permissions, hence the segmentation fault when trying to access it).
I'm not entirely sure the purpose of your snippet, but the following code will work, and perhaps it will help:
int myvar = 5;
int *p = nullptr;
p = &myvar;
cout << myvar << endl;
cout << &myvar << endl;
cout << p << endl;
cout << *p << endl;
(Note: I used two lines for setting 'p' because that is how you did it in your snippet. You could easily just use: int *p = &myvar; )
Anyway, there are scope issues here as p will only be valid as long as myvar is in scope; however, this does illustrate the basics of pointers. myvar and *p will return the same value (the value being pointed to), and &myvar and p will return the same value (the location of value in memory.)
Related
I thought the following code snippets would cause double free, and the program would core dump. But the truth is that there is no error when I run the code?
Similar problem shows that it caused double free!
My Question is why does there have no error show that there is a double free? And why does there have no core dump?
#include <iostream>
using namespace std;
int main()
{
int *p = new int(5);
cout << "The value that p points to: " << (*p) << endl;
cout << "The address that p points to: " << &(*p) << endl;
delete p;
cout << "The value that p points to: " << (*p) << endl;
cout << "The address that p points to: " << &(*p) << endl;
delete p;
cout << "The value that p points to: " << (*p) << endl;
cout << "The address that p points to: " << &(*p) << endl;
delete p;
}
The program's output when I ran this program is shown as followed:
After modifying the code snippet like the following, the core dump occured:
#include <iostream>
using namespace std;
int main()
{
int *p = new int(5);
for (;;)
{
cout << "The value that p points to: " << (*p) << endl;
cout << "The address that p points to: " << &(*p) << endl;
delete p;
}
return 0;
}
And the program output is :
So there is another question that why this program will core dump every time?
Yes, it is a double free (well, triple, really) which puts it into undefined behaviour territory.
But that's the insidious thing about undefined behaviour, it's not required to crash or complain, it's not required to do anything at all(a). It may even work.
I can envisage an implementation that stores the free state of a block in the control information for it so that freeing it twice would have no effect. However, that would be inefficient, and also wouldn't cover the case where it had been reallocated for another purpose (it would prevent double frees, but not a piece of code freeing the block when some other piece still thinks it still has it).
So, given it's not required to work, you would be well advised to steer clear of it since it may also download maniacal_laughter.ogg and play it while erasing your primary drive.
As an aside, modern C++ has smart pointers that are able to manage their own lifetime, and you would be doing yourself a big favour if you started using those instead of raw pointers.And, although the removal of raw pointer from C++ was a joke, there are some that think it's not such a bad idea :-)
(a) The C++20 standard has this to say when describing undefined behaviour in [defns.undefined] (my emphasis):
Behavior for which this document imposes **NO** requirements.
why does there have no error show that there is a double free? And why does there have no core dump?
delete p;
cout << "The value that p points to: " << (*p) << endl;
The moment you referenced to a deleted pointer is when the program entered an undefined behaviour, and then there is no guarantee that there would be an error or a crash.
It's not entirely the same, but the analogy between memory and a hotel room is applicable, which explains well what an undefined behaviour means. Highly recommended reading:
Can a local variable's memory be accessed outside its scope?
After a pointer is initialized, do you have to use the * dereference operator to call the pointer in a condition?
Example:
int main()
{
int var = 10;
int *ptr = &var;
if(ptr) // does this need to be if(*ptr) ???
{.......}
}
And can I have a short explanation as to why?
Thank you.
if (ptr)
check if the pointer is not Null but
if (*ptr)
check if the value it points to is not zero (in this example is 10)
So for checking the value you shoud add *.
It depends on what you want to do.
if(ptr) checks if the pointer value is nullptr or not. Note that this is shorthand for if(ptr != nullptr).
if(*ptr) checks if what the pointer points to is nullptr (or 0) - and in that case, since you dereference (follow) the pointer to answer the question, the pointer itself had better not be nullptr in that case.
First of all, a pointer is only a variable. However, there are different contexts in which you can use it.
As any other variable you can access the pointers content (which is the adress of the underlying memory) as follows:
int i = 1;
int * p = &i;
std::cout << p << std::endl
this would output the adress of i since this is what is stored in p
If you however want to access the content of the underlying memory (the value of i), you need to dereference the pointer first by using the * operator:
std::cout << *p << std::endl;
This would print the value of iso 1.
of course you can also access the pointer's adress (since the adress of i is a numeric value as well and needs to be stored somewhere too):
std::cout << &p << std::endl;
That would output the adress of p so the adress where the adress of i is stored :)
As a little example try to run this code:
#include <iostream>
int main() {
int i = 1;
int * p = &i;
std::cout << "Value of i(i): " << i << std::endl
<< "Adress of i(&i): " << &i << std::endl
<< "Value of p(p): " << p << std::endl
<< "Dereferenced p(*p): " << *p << std::endl
<< "Adress of p(&p): " << &p << std::endl
<< "Dereferenced adress of p(*(&p)): " << *(&p) << std::endl;
}
I am trying to cout the address of the variable abc and the program just crash
int main()
{
int *app;
int abc = 2;
*app=3;
cout << *app << endl << &*app << endl << abc;
cout << &abc;
}
However, if I remove the address variable int *app , then it will cout the address of abc
int main()
{
int abc = 2;
cout << &abc;
}
I have no idea why would the existence of another unrelated address variable would affect it. Please advise.
The problem lies here:
*app=3;
this will probably cause a Segmentation Fault, Undefined Behavior.
If you remove it, it makes sense to see the expected output.
What are you trying to do?? This is undefined behavior.
int *app; // pointer is not initialized.
int abc = 2;
*app=3; // de-referencing an uninitialized pointer. Bad.
I'm having some trouble understanding pointers. In the following code, I'm trying print the address of a variable in 2 ways-once using the address operator and then using pointers:
#include<iostream>
using namespace std;
int main (void)
{
int x = 10;
int *int_pointer;
int_pointer = &x;
cout << "x address=" << &x << endl;
cout << "x address w pointer=" << int_pointer << endl;
return 0;
}
x address = 0028FCC4
x address w pointer = 0028FCC4
This works as expected. But when I do the same thing but now using character type variable, I get some trash output:
#include<iostream>
using namespace std;
int main(void)
{
char c = 'Q';
char *char_pointer;
char_pointer = &c;
cout << "address using address operator=" << &c << endl;
cout << "address pointed by pointer=" << char_pointer << endl;
return 0;
}
address using address operator=Q╠╠╠╠£åbªp é
address pointed by pointer=Q╠╠╠╠£åbªp é
I have no idea why this is happening. Thanks in Advance.
The C++ library overloads the << operator for certain types. (char*) is one of them. Cout is trying to print a string, an array of characters terminated by a null character.
Just cast the pointer:
cout << "address pointed by pointer" << ( void* )char_pointer << endl;
or
cout << "address pointed by pointer" << static_cast<void*>(char_pointer) << endl;
The reason it prints out junky stuff is because your char does not have a null terminator which means the program will keep searching for one until, and in the process will print out whatever it finds. The text you see is ASCII but referenced by the address which the ostream is misinterpreting. To get the address held in memory, you could use implicit conversion or a static_cast. I prefer the latter:
cout << "address pointed by pointer=" << static_Cast<void*>(char_pointer) << endl;
Like 2501 said, in different wording, &c, since c is a char, equals a char *, so it's going to try to print until the new line character '\0' that is either implicitly or explicitly put in character arrays going to std::cout so the stream knows where the end of the character array is.
So, yeah use the (void *) like 2501 said.
What happens when I do this? When I remove the first initialization to "boo1", it prints boo2 but now it still prints nothing. Does this mean that the pointer allocate a random memory and assign "boo1" value to it and now I can't access it or what?
string *p;
*p="boo1";
p=new string;
*p="boo2";
cout << *p; //prints nothing
line 1: "p" contains random value, i.e. refers to random memory address.
line 2: random memory block referred by "*p" is interpreted as string instance. This instance is assigned by "boo1".
Try so:
string *p = new string;
*p = "boo1";
cout << *p << '\n';
*p = "boo2";
cout << *p << '\n';
delete p;
Remember that:
std::string is not the same as stupid char[] array!
All pointers must be assigned before usage!
All "new" must have corresponding "delete"!
If you declare a string as pointer ( string *p ), you must allocate memory for it,
so the correct way to do the job is:
string *p = new string;
*p = "boo1";
cout << *p << '\n';
*p = "boo2";
cout << *p << '\n';
The previous answers are correct, however why not using a reference, it seems more convenient in your case.
Something like :
std::string p;
p = "boo1";
std::cout << p << std::endl;
p = "boo2";
std::cout << p << std::endl;
Regards,
Michel.