This code doesnot work on devC++ - c++

#include<iostream>
using namespace std;
int main()
{
int *p;
*p=9;
cout<<*p<<endl;
return 0;
}
Why is this code not executing in devc++?

You never allocated any memory for p so you have an uninitialized pointer pointing to garbage. Once you dereference it is undefined behavior.
int *p;
Should be
int *p = new int;
And then you need a
delete p;
before the end of main as every new/new[] should be matched with a delete/delete[].
But in this case there is no reason to even do that. Just use a regular int and you have
int main()
{
int p = 9;
std::cout<< p << '\n';
return 0;
}

Related

Does the following program contain a dangling reference?

I have the following program:
#include <iostream>
#include <string>
using namespace std;
using int_arr = int[3];
int& f(int_arr& arr, int index)
{
return arr[index];
}
int main() {
int arr[3] = {1, 2, 3};
int& g = f(arr, 0);
g = 5;
std::cout << arr[0] << std::endl;
}
Is arr[index] returned by f considered a dangling reference?
I don't think this is a dangling reference since the arr object continues to exist even after f returns (so the reference is valid), but I wanted to confirm my understanding. I compiled this with -fsanitize=undefined and it compiled fine and produced the expected output.
No, arr and g have the same life time, so there's no dangling reference.
Note however that you can easily create a dangling reference with your function:
int empty;
int& ref = empty;
int &f(int arr[], int idx) { return arr[idx]; }
void g()
{
int arr[] = { 1, 2, 3 };
ref = f(arr, 0);
}
int main()
{
g();
// ref is accesable here and complete garbage
}

How to make the function pointer work in this case?

I'm trying to write an example code for the following line of code:
int (*(*foo)(const void*))[3];
I got this code from here (at each refresh of the website you get a different piece of code and there is a finite set of them so by reloading a couple of times you will get my example). I wanted to see out of curiosity is it even possible to write some code that would make this line work.
Here is what I wrote so far:
#include<stdio.h>
#include<malloc.h>
int* goo(const void * ptr) {
int* ret = (int*) malloc(sizeof(int) * 3);
if (!ret)
return NULL;
for (int i = 0; i < 3; ++i)
ret[i] = i;
return ret;
}
int doo() { return 0; }
int main(void) {
//NOTE: Following 2 lines have syntax errors
int (*(*foo)(const void*))[3] = &goo;
int* values = foo(goo(doo));
for (int i = 0; i < 3; ++i) {
printf("%d", values[i]);
}
free(values);
return 0;
}
If I understood correctly, foo should be some function that receives as an argument another function and returns an int array of size 3. The problem is I don't know how to make foo in this case point to a function or even how to get the int array.
Is it even possible to make this line of code work?
If I understood correctly, foo should be some function
foo is a pointer to a function.
that receives as an argument another function
No, the parameter type of the function that foo points to must be a pointer to const void i.e. const void*. A pointer to void is an object pointer. It can point to an object of any type.
Functions are not objects, but on some systems, pointers to functions can be reinterpreted as pointers to void.
and returns an int array of size 3.
No; Return types cannot be arrays. The function must return a pointer to an array of 3 ints i.e. int(*)[3].
Is it even possible to make this line of code work?
Here is an example program that uses such foo. It doesn't make much sense, but that's because the goal is to use an obscure function pointer:
#include<iostream>
int arr[] {
1,
2,
3,
};
int (*goo(const void*))[3] {
return &arr;
}
int main() {
int (*(*foo)(const void*))[3] = &goo;
int (*values)[3] = foo(nullptr);
for (int i : *values) {
std::cout << i << " ";
}
}
We can greatly improve readability by introducing type aliases:
using IntArr3 = int[3];
using FooFun = IntArr3*(const void*);
IntArr3* goo(const void*) {
return &arr;
}
int main() {
FooFun* foo = &goo;
IntArr3* values = foo(nullptr);
for (int i : *values) {
std::cout << i << " ";
}
}

Why access deleted pointer won't crash the program?

#include <iostream>
#include<list>
using namespace std;
template <class T>
class Ptr {
public:
Ptr() {
a = nullptr;
l.push_back(0);
}
std::list<int> l;
void print_this() {
cout<<this<<endl;
}
protected:
int *a;
};
int main()
{
Ptr<int> *ptr = new Ptr<int>();
delete ptr;
//ptr = nullptr; //if uncomment this line will crash
auto p = &(ptr->l);
cout<<"p is "<<p<<endl;
ptr->print_this();
ptr->l.push_back(1);
cout<<"size is "<<ptr->l.size()<<endl;
cout<<"end";
return 0;
}
I run code here: https://www.programiz.com/cpp-programming/online-compiler/
output is :
p is 0x5628eb47deb0
0x5628eb47deb0
size is 2
end
if I set ptr to nullptr after delete, it will crash at push_back. But still fine when I access the list.
How is it even possible that I push data to a dangling pointer without crashing it??
When you have a pointer to a class, and call a non-virtual function on it, whatever the address is at the pointer will be considered the this pointer. Even if it is zero. As long as you don't try to access members at that address, you should have no problem printing the this poniter.
struct A {
void printThis() {
printf("%d\n", this);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A * a = (A*) 777;
a->printThis(); // will print 777
a = NULL;
a->printThis(); // will print 0
return 0;
}
When you delete a pointer and don't set its address to null, the previous address value is kept.
Accessing a deleted pointer is undefined behavior. It is not required to crash. It just may be that the random data that you are pointing to has some meaning somewhere else in the program. It may even be your old data. Deleting a pointer tells the system it can reuse that memory, but it may not have had time to reuse it yet, and so the old data could still be visible.
Finally your program crashes when you uncomment your line because that sets ptr = 0, and &(0x0000000->l) is an invalid memory reference.
Pointer continues to reference to the address after you delete it. You can still use the pointer but there will be trash(mostly) in the address.
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int *ptr_a = &a;
int *ptr = &a;
cout << *ptr_a << endl;
cout << *ptr << endl;
delete ptr;
*ptr_a = 2;
cout << *ptr << endl;
}
Result:
1
1
2

Pointer address assignment in c++ [duplicate]

This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 1 year ago.
i'm code beginner
#include <bits/stdc++.h>
using namespace std;
void init(int* arr){
arr = new int[10];
cout << arr << endl;
}
int main(int argc, char* argv[]){
int *arr;
init(arr);
cout << arr << endl;
}
this is a simple code.
My question is that why arr's address in init function and arr's address in main function is different?
My think is that i gave arr's address to init function and in init function, arr is assigned a new address through 'new int[10]'
So, arr's address in init function and in main will be same.
but this code doesn't work as i think.....
Can you tell me why?
Step back a little and think about how arguments are passed into functions.
void foo(int x) {
}
int main() {
int x;
foo(x);
}
Here the x in main() is actually passed by value to foo() which means a copy of x is created when passing to foo().
With the same logic, if you think of int * as another variable type
using intPtr = int*; //a sort of typedef
void foo(intPtr x) {
}
int main() {
intPtr x;
foo(x);
}
a copy of x is again created. This is what is happening in your program. For what you expect, you need to pass in the variable by reference
using intPtr = int*;
void foo(intPtr& x) {
}
int main() {
intPtr x;
foo(x);
}
Adapting the same to your program:
#include <iostream>
void init(int*& arr){
arr = new int[10];
std::cout << arr << '\n';
}
int main(int argc, char* argv[]){
int *arr;
init(arr);
std::cout << arr << '\n';
delete(arr);
}
There's another way with pointers that is using a pointer to a pointer (**)
#include <iostream>
void init(int** parr){
*parr = new int[10];
std::cout << *parr << '\n';
}
int main(int argc, char* argv[]){
int *arr;
init(&arr);
std::cout << arr << '\n';
delete(arr);
}
where the address of arr (&arr) is passed into the function. Inside the function, the contents of parr is modified (which is arr in this case).

Moving a pointer through array - passing by reference or incrementation?

I have absolutely no clue, what the difference is between the two following examples:
void function(int *p) {
p++;
}
int main() {
int values[] = {1,2,3};
int *p = values;
function(p);
cout << *p;
return 0;
}
This one returns "1".
Whereas a slight modification yields "2" (which is the wanted result):
int main() {
int values[] = {1,2,3};
int *p = values;
p++;
cout << *p;
return 0;
}
Where lies the problem? Is it due to passing by reference or incrementing?
The issue here is
void function(int *p) {
p++;
}
Is using pass by value - not pass by reference. Since the pointer is passed by value any change you make to the pointer itself is not reflected in the call site. If you need to modify where the pointer points then you need to pass it by reference like
void function(int*& p) {
p++;
}
Now when you increment it will point to the second element like it does in your second example.
In this example
void function(int *p) {
p++;
}
int main() {
int values[] = {1,2,3};
int *p = values;
function(p);
cout << *p;
return 0;
}
You are passing a pointer by value, which means you simply pass a copy of the address the pointer is pointing at. You then proceed to increment the function's local copy of that pointer and then exit the function. This has no effect on the original pointer as you incremented a local copy.
In this example, however
int main() {
int values[] = {1,2,3};
int *p = values;
p++;
cout << *p;
return 0;
}
You directly increment your pointer, which means it is now pointing at the next element in the array.
In the first case the value of address is passed by value.
function(p) ==> void function(int *p){}
The 'p' on right side a local variable. So any modification to the pointer will be visible only inside function.