Getting segmentation fault with c++ pointers - c++

So I'm trying to familiarise myself with c++ pointers by running the following code.
#include <iostream>
using namespace std;
int main(void){
int* x;
cout << &x << endl;
return 0;
}
which works fine and prints the pointer value of x but
#include <iostream>
using namespace std;
int main(void){
int* x;
*x = 100;
cout << &x << endl;
return 0;
}
gives me a segmentation fault when I try to tun it. Why is this? I don't see how that extra line should change anything about the address of x.

You did not allocate an object which you are going to assign.
int* x;
The value of x is unspecified and can be any arbitrary value. So the next statement
*x = 100;
is invalid.
You have to write
x = new int;
*x = 100;
Or
x = new int( 100 );
Or even
x = new int { 100 };
provided that your compiler supports the list initialization for operator new which was introduced in the C++ 2011..

and prints the pointer value of x but
Not exactly.
std::cout << &x; it prints x's address (the pointer's address);
std::cout << x; prints the address, x points to;
std::cout << *x; prints what x points to;
int* x;
*x = 100;
Here, x is just a pointer, you need to allocate memory for the 100. For example
int* x = new int;
*x = 100;
std::cout << *x;
Or just
int* x = new int( 100 );
std::cout << *x;
Without allocating memory and leaving x uninitialized, by *x = 100 you're trying to change some random memory, which leads to undefined behavior.

You have undefined behaviour.
Your first example is fine since &x (which has type int**) is the address of a stack allocated pointer. One of the << overloads in cout is defined to output that correctly.
In the second example, you are dereferencing a pointer that is not pointing to anything. That's undefined behaviour; hence the crash. If you'd written
int y;
int* x;
x = &y;
*x = 100; /*this means that y is now 100*/
then all would have been well since now x is pointing to something.

Related

Illegal hardware instruction on a c program compiled on Mac

I am getting an illegal hardware instruction error when compiled on mac. Appreciate any pointers.
#include<iostream>
using namespace std;
int * fun(int * x)
{
return x;
}
int main()
{
int * x;
*x=10;
cout << fun(x);
return 0;
}
Pointers are just pointers. In your code there is no integer that you could assign a value to.
This
int * x;
Declares x to be a pointer to int. It is uninitialized. It does not point anywhere. In the next line:
*x=10;
You are saying: Go to the memory that x points to and assign a 10 to that int. See the problem? There is no int where x points to, because x doesnt point anywhere. Your code has undefined behavior. Output could be anything.
If you want to assign 10 to an int you need an int first. For example:
#include<iostream>
using namespace std;
int * fun(int * x)
{
return x;
}
int main()
{
int y = 0;
int * x = &y;
*x=10;
cout << fun(x);
return 0;
}
This assigns 10 to y. The cout is still printing the value of x, which is the adress of y. It does not print the value of y. Not sure what you actually wanted.
The problem is that in your program the pointer x is not pointing to any int variable. So first you have to make sure that the pointer x points to an int object as shown below.
You can sovle this as shown below:
int i = 0; //create the int object to which x will point
int *x = &i; //make x point to variable i
*x = 10; //dereference the pointer x and assign 10 to the underlying variable i
cout << *fun(x); //this prints 10

Why is pointer not printing any value?

I am trying basic c program using pointers, Here's my code
#include <stdio.h>
int main()
{
int *p;
for(int i=0;i<10;i++){
*p = &i;
printf("%d",*p);
}
return 0;
}
Output:
main.c:16:12: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
*p = &i;
^
...Program finished with exit code 0
And the value is not printed. Is there any problem in assigning variable i which persists from for loop to pointer?
P is the pointer. Therefore, assign the pointer to it as follows.
p = &i;
Then use it as follows in your code.
#include <stdio.h>
int main()
{
int *p;
for(int i=0;i<10;i++){
p = &i;
printf("%d",*p);
}
return 0;
}
With fix and more C++ style using std::cout for output.
(Why not use printf() in C++)
#include <iostream>
int main()
{
int* p{ nullptr }; // initialize before use.
for (int i = 0; i < 10; i++)
{
p = &i;
std::cout << *p << " ";
}
return 0;
}
Use this code.
It'll work, I think
int* p =NULL;
*p = sizeof(i); // casting int to pointer
Here P is an integer Pointer, And pointer is a variable which store the address of the another variable. So you have to assign the the address of variable (i) to variable (p), like
p=&i;
In this line you are storing the address of i in variable p.
When you point p like, *p it will give you the value present at that address.
#include <stdio.h>
int main()
{
int *p;
for(int i=0;i<10;i++){
p = &i;
printf("%d",*p);
}
return 0;
}

Passing Pointers By Reference vs Passing Pointers Into Functions

It's been a while since I've coded anything in C++. While I was trying to help another person as a CIS Tutor, he wanted to know why it's necessary to have an ampersand next to a pointer to an int.
I figured that if you were to pass a pointer by reference and you point to something else, the main knows after you passed that val will equal to whatever you set it equal to.
There will be an example below will demonstrate what I'm trying to say.
Is this correct?
//main function
int variable = 0;
int* val = &variable;
function1(val);
cout << *val << endl;
function2(val);
cout << *val << endl;
//Passing in a pointer with reference.
void function1(int*& value)
{
int variable = 9;
value = &variable;
}
//Passing in a pointer without reference.
void function2(int* val)
{
int variable = 9;
value = &variable;
}
My assumption is that the program will output 9 instead of 8 or 0. I hope this give you guys a clear picture of what I'm trying to ask.
The difference between passing the values and passing the reference is the same with pointers as with other values (actually pointers are nothing special they just hold numbers that sometimes are adresses of other objects).
With int:
void foo(int x) { x = 1; }
void bar(int& x) { x = 2; }
int main() {
int y = 5;
foo(y);
std::cout << y; // prints 5
bar(y);
std::cout << y; // prints 2
}
Now with pointers:
void foo(int* x) { x = 0; }
void bar(int*& x) { x = 0; }
int main() {
int y = 42;
int* z = &y;
foo(z);
std::cout << z; // prints the address of y
bar(z);
std::cout << z; // prints 0
}
Note that your function1 is broken, because when you call it
int* y;
function1(y);
std::cout << *y; // **baaam**
// the value y points to is already gone
the int inside the function ends its lifetime when the function returns and the caller cannot use the value in any meaningful way. Note that in this particular example you would probably get the "correct" value printed, but that is just by coincidence and dereferencing y after passing it to function1 is undefined behaviour.

unique pointer vs raw pointer

Trying to understand the unique_pointer vs raw pointer access
#include <iostream>
#include <memory>
int main() {
int a = 10;
int *x = &a;
int *y = &a;
std::unique_ptr<int> p1 = std::make_unique<int>(a);
std::cout<<*x<<*p1<<*y<<"\n";
// prints 101010
*p1 = 20;
std::cout<<*x<<*p1<<*y<<"\n";
// prints 102010
*x =30;
std::cout<<*x<<*p1<<*y<<"\n";
// 302030
return 0;
}
Output
101010
102010
302030
Program ended with exit code: 0
In the above code x, y,p1 are all pointing to variable a;
so change of value a should have reflected to all the pointers dereferencing .
Please do help me to understand the behaviour I am few of the guys who all are now moving from use of raw pointers to smart pointers.
You're wrong, p1 doesn't point to a.
Instead std::make_unique<int>(a) create a brand new int object and initialize it to the current value of a.
To make p1 point to a you need to do
std::unique_ptr<int> p1(&a);
However that brings with it other problems, like p1 taking over the ownership of &a, and attempting to free that memory when p1 is destructed (which is not possible).
You could use the Boost null_deleter to avoid the last problem.
But I recommend that in most situation you should not look at the smart pointers a simple self-deleting pointers, but instead from an ownership perspective.
The code below is based on MSVC.
Reason
std::make_unique() let you make new object, not reference the parameter
You can find that the unique_ptr p1 gets a different address
int a = 10; // &a = 0x000000bd7d5dfb74
int* x = &a; // x = 0x000000bd7d5dfb74
int* y = &a; // y = 0x000000bd7d5dfb74
std::unique_ptr<int> p1 = std::make_unique<int>(a); // p1._Mypair._Myval2 = 0x00000288fbbd6ba0
std::cout << *x << *y << *p1 << "\n";
*p1 = 20;
std::cout << *x << *y << *p1 << "\n";
*x = 30;
std::cout << *x << *y << *p1 << "\n";
Solution
As Some programmer dude said, use std::unique_ptr<int> p1(&a);
This results that the unique_ptr indicates the same address
int* a = new int(10); // a = 0x0000027411117260
int* x = a; // x = 0x0000027411117260
int* y = a; // y = 0x0000027411117260
std::unique_ptr<int> p1(a); // p1._Mypair._Myval2 = 0x0000027411117260
std::cout << *x << *y << *p1 << "\n";
*p1 = 20;
std::cout << *x << *y << *p1 << "\n";
*x = 30;
std::cout << *x << *y << *p1 << "\n";
FYI, as the unique_ptr p1 will free the memory of a, you do not need to free the memory explicitly.

Dynamic memory allocation of array in C & C++

Look at the user input in C and C++ code (inside for loop).We use *(p+i) in user input in C++ and (p+i) in C. Whats the reason for missing * in C?
Plz explain! Take a look at the COMMENT line... inside for loop
#include <iostream>
using namespace std;
int main()
{
int n,i;
cout << "Ent size" << endl;
cin>>n;
int *p = new int [n];
for(i=0;i<n;i++)
cin>>*(p+i);//LOOK AT THIS LINE
cout<<"------------\n\n";
for(i=0;i<n;i++)
cout<<*(p+i)<<endl;
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
printf("Ent size!\n");
scanf("%d",&n);
int *p=(int *)malloc(n*sizeof(int));
int i;
for(i=0;i<n;i++)
scanf("%d",(p+i));//LOOK AT THIS LINE
printf("-------\n\n");
for(i=0;i<n;i++)
printf("%d\n",(p+i));
return 0;
}
The difference exists due to the existence of references in C++.
In C++ operator >> for objects of type int is declared the following way
basic_istream<charT,traits>& operator>>(int& n);
As you see the parameter of the operator has type int &. It means that the argument is passed to the function by reference that is the function deals directly with the argument not with its copy.
So this statement
cin>>*(p+i);
is equivalent to
cin.operator( *( p + i ) );
and the compiler does not creates a copy of the object specified by the expression *( p + i ). It uses the object itself because the object is passed by reference.
In C in fact there is also used a reference to the argument but it is specified as a pointer because the notion of references is not defined in C.
When somebody says that an object is passed by reference to a function in C it means that the object is passed indirectly using a pointer to the object.
In C++ it means that there is used the notion of the reference.
So if you want that function scanf would store the input data in the object itself you have to pass it indirectly to the function by using a pointer to the object.
scanf("%d",(p+i));
Here p + i is a pointer to object *( p + i ).
Consider these two simple programs
C++
#include <iostream>
int main()
{
int x = 10;
int &rx = x;
std::cout << "x = " << std::endl;
rx = 20;
std::cout << "x = " << std::endl;
}
The same in C can be written the following way using a pointer because C does not have the notion of references
C
#include <stdio.h>
int main( void )
{
int x = 10;
int *rx = &x;
printf( "x = %d\n", x );
*rx = 20;
printf( "x = %d\n", x );
}