#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
Related
I'm pretty new to c++ and I'm stuck at this problem.
I append a struct pointer(Bar*) to a vector and that struct have a pointer class member(Foo*).
struct Bar
{
const int var{ 0 };
Foo* m_foo{ nullptr };
};
std::vector<Bar*> list;
int main()
{
Bar* p_Bar = new Bar;
p_Bar->m_foo = new Foo;
list.emplace_back(p_Bar);
}
I have a thread that checks validity of these pointers. Once I delete those pointers, vector element should exist and I should check whether both pointers are valid or not.
When any of them is invalid, I should erase that vector element(after check I mean).
Here's my try:
#include <iostream>
#include <vector>
#include <thread>
class Foo
{
public:
Foo() {};
const int var{ 5 };
};
struct Bar
{
const int var{ 0 };
Foo* m_foo{ nullptr };
};
std::vector<Bar*> list;
bool _check = true;
void Check()
{
while (_check)
{
for (int c = 0; c < (int)list.size(); c++)
{
Bar* p = list[c];
if (p)
{
if (p->m_foo)
{
std::cout << "m_foo->var:" << p->m_foo->var << "\nEnter anything to delete the element: ";
}
else
{
std::cout << "m_foo was nullptr";
}
}
else
{
std::cout << "Element was invalid";
}
}
std::this_thread::sleep_for(std::chrono::duration(std::chrono::seconds(2)));
}
}
int main()
{
Bar* p_Bar = new Bar;
p_Bar->m_foo = new Foo;
list.emplace_back(p_Bar);
std::thread thread1(Check);
thread1.detach();
std::string t;
std::cin >> t;
if (list[0]->m_foo)
delete list[0]->m_foo;
if (list[0])
delete list[0];
list.clear();
std::cin >> t;
_check = false;
return 0;
}
To check whether the pointer was deleted or not, I should use NULL or nullptr which actually means 0.
But once the pointer is deleted, the address will be something like this 0xFFFFFFFFFFFFFFFF and IDE will throw this kind of exception:
Exception thrown: read access violation.
p->m_foo was 0xFFFFFFFFFFFFFFFF.
How to check whether the pointer's deleted/pointer's address is valid or not?
How to check whether the pointer's deleted/pointer's address is valid or not?
It isn't possible to check whether a pointer is valid or invalid. If a pointer is valid or null, then you can check which one it is. If a pointer is invalid, then the result of the comparison will be unspecified.
Besides comparing an invalid pointer, your program has another bug: You're deleting in one thread, and accessing the pointer in another without synchronising the operations. Similarly, you're accessing the elements of the vector while its elements are removed in another thread. The behaviour of the program is undefined.
P.S. Avoid owning bare pointers.
You could use automatic_ptr class instead classic in-build pointer.
You can develope yourself, or use eg. std::unique_ptr and std::shared_ptr.
Principe of this classes is, that pointer is encalupsed in thos class and class count external links (pointers...) and store it to internal attribute.
In each book of C++ is example for it.
I am trying to understand how unique pointers and move semantics. Now, I have created a dummy example below to show what the issue is. My question is, why does this code throw a pointer being freed was not allocated error?:
#include <iostream>
#include <memory>
using namespace std;
template <class T>
class Object
{
public:
T *values = nullptr;
int size;
Object(int size) : size(size)
{
values = new T[size];
}
~Object()
{
delete[] this->values;
}
void myFunc(T *&&new_values)
{
cout << "myFunc called!" << endl;
delete[] this->values;
values = new_values;
}
void print()
{
for (int i = 0; i < size; i++)
cout << this->values[i] << " ";
cout << endl;
}
};
int main()
{
auto my_object = new Object<int>(4);
std::unique_ptr<Object<int>> my_other_object(new Object<int>(4));
int values[4] = {1, 2, 3, 4};
int my_other_values[4] = {10, 20, 30, 40};
/* This works all fine! */
my_object->myFunc(std::move(values));
my_object->print();
/* This next bit throws pointer being freed was not allocated */
my_other_object->myFunc(std::move(my_other_values));
my_other_object->print();
}
This has nothing to do with std::unique_ptr. The reason you get the "pointer being freed was not allocated" error is because the shown code is trying to delete something that was not newed.
delete[] this->values;
values = new_values;
This properly deletes the old values, but then just blindly sets values to point to something that was never newed (the new_values that get passed into here are not newed anywhere).
Hence, later, this object's destructor attempts to delete what's now in values, but it was never newed (it just points to some static array) and you get the runtime error.
I have one question. Is it possible to delete a pointer with function? This is my example:
void deletePointer(auto* pointer)
{
delete pointer;
pointer = nullptr;
}
int main()
{
int value = 5;
int* value_ptr = &value;
//Some code
deletePointer(value_ptr);
return 0;
}
And it doesn't work. I also tried adding "inline" keyword to function and with lambda.
auto deletePointer = [&](auto* pointer) -> void
{
delete pointer;
pointer = nullptr;
}
I think it only deletes pointer inside of function, lambda. Is it possible to make function that will delete pointer, which is passing to function?
Solution.
I got to know that delete can be used only when object is creating using new. So I changed code a bit.
#include <iostream>
void deletePointer(auto*& pointer)
{
delete pointer;
pointer = nullptr;
}
int main()
{
int* ptr = new int(5);
deletePointer(ptr);
if (ptr == nullptr) std::cout << "Succeed";
else std::cout << "Failed";
return 0;
}
And given output from code is: Succeed.
So now everything works.
Thanks for help :)
I am at the point learning classes/destructors in c++ and the need to return a pointer from a class member:
size_t * classname :: function();
but it doesn't work.
My logic is to declare a class variable e.g. classname * p_p = classfunction(data); that should access the class member:
size_t * classname :: classfunction(data)
{
//... do something ...
new p_p;
return p_p;
}
So the pointer address in theory gets returned to the main() variable p_p each time the member function of the class gets called.
Or should but doesn't and the program crashes somehow but not even sure on which point.
There is no compiler warning or error and the
debugger doesn't stops anywhere and I find nothing on returning a pointer from a class member function at all nor that it isn't allowed or something.
Also if there IS a syntax to return a pointer from a class member function I would need to have a syntax for delete the "new p_p".
So my question is: Should it work and how would I get this running or why is that maybe it is not working or forbidden? In my logic it should be a proper way but I may be wrong somehow and classes doesn't support this function completely.
EDIT:
Thanks to your answers and comments I got the pointer returned from the class member. (Also changed size_t to int since its just a pointer.) Like you suggested in the comments I added a minimal reproducible example:
#include <iostream>
using namespace std;
//########## class without ~ destructor ##########
class classname
{
public:
int *ptr;
int *classfunction(int);
void delete_classfunction(int*);
};
void classname::delete_classfunction(int*ptr)
{
delete[] ptr;
ptr = nullptr;
}
int *classname :: classfunction(int value)
{
int* ptr = new int[value]; //no delete?
ptr[0] = 5;
return ptr;
}
//########## class with ~destructor ##########
class classname_c
{
public:
int *ptr;
int value;
*classname_c(int );
void print(int*);
~classname_c();
};
void classname_c::print(int* ptr)
{
cout << ptr[0] << " shows value" << endl;
}
*classname_c::classname_c(int value)
{
int* ptr = new int[value];
ptr[0] = value;
} /*Brings warning: control reaches end of non-void function [-Wreturn-type]
48 | }
| ^*/
classname_c::~classname_c ()
{
cout << ptr[0] << endl;
delete[] ptr;
ptr = nullptr;
cout << ptr[0] << endl;
}
int main()
{ //class and deleting it myself calling the function delte
int value = 3;
int *ptr;
classname call;
ptr = call.classfunction(value); //create new ptr
cout << ptr[0] << " shows value" << endl;
call.delete_classfunction(ptr); //free memory
cout << ptr[0] << " shows value succ. deleted" << endl;
//class with destructor
classname_c dest(value);
dest.print(ptr);
cout << ptr[0] << " shows value succ. deleted" << endl; //its not!
return 0;
}
brings the following output:
5 shows value
0 shows value succ. deleted //How it should be
3 shows value
3 shows value succ. deleted //but its not, why? What did I do wrong?
Press <RETURN> to close this window...
Now I am not sure if/when the ~destructor is working or how I can test if I created the destructor right, because the ptr value is not deleted.
Also can I fix the
warning: control reaches end of non-void function [-Wreturn-type]
48 | }
| ^
It is perfectly fine to return a pointer from a member function, although returning a pointer to an allocated size_t seem a bit overkill.
What you want is probably something like this:
#include <iostream>
class cls
{
public:
size_t *ptr_func();
};
size_t *cls::ptr_func()
{
size_t *p = new size_t(42);
return p;
}
int main()
{
cls c;
size_t *p = c.ptr_func();
std::cout << (void *)p << '\n';
std::cout << *p;
delete p;
}
This may not answer your question but it might illustrate why this is not working how you expect. When you call a member function of a class, i.e. classname::function(), you need to have an instance of that class on which to call it. Something which has been defined like
class classname {
public:
classname() {ptr = new int(0);}
size_t* function();
~classname();
int* ptr;
};
size_t* classname::classfunction() {
size_t* ptr = new size_t();
return ptr;
}
Cannot be called by
classname * p_p = classfunction();
because classfunction() is not being called on an instance of classname and because classname is not size_t so you can't assign classname to the return from a function which returns type size_t unless a cast from one to the other has been explicitly defined (same goes for classname* and size_t*). You can do something like this
classname cls;
size_t* ptr = cls.classfunction();
Also note that destructors are not used for member functions, only for classes, so the syntax ~size_t*class::function() doesn't really make sense.
If you are trying to get a pointer to a class instance you can simply do
classname * ptr = new classname();
and put your //... do something ... in a constructor.
Edit
The use of a destructor is to perform the
[...] necessary cleanup needed by a class when its lifetime ends.
This means that the destructor is called when the instance of said class goes out of scope or is manually deleted. So when you have a class defined as above, with the destructor
classname::~classname() {
delete ptr;
}
This means that ptr will be deleted when the instance of classname reaches the end of its "lifetime". E.g.
int main() {
classname* cls = new classname();
// cls->ptr == int(0)
delete cls; // Calls ~classname()
// cls->ptr == NULL
}
The same is true for stack allocation (classname cls();) and in either case the destructor would be called automatically at the end of main (if that instance had not already been manually deleted).
Now what you can't do is delete a pointer that was allocated outside the class instance - if you want to be able to control a pointer like that while still having it accessible from outside the class you can make it a public member, as I did in the edited class declaration. This allows you to access the pointer from outside the class and then still delete it with the destructor,
int main() {
classname* cls = new classname();
// cls->ptr == 0
cls->ptr = 3;
// cls->ptr == 3
delete cls;
// cls->ptr == NULL
}
Hopefully that offers some clarity.
The warning is because of the constructor
*classname_c::classname_c(int value) {//...}
.... don't do this until you really know what you're doing, if you want a pointer to an instance of the class the constructor should be
classname_c::classname_c(int value) {//...}
and you should create the instance with
classname_c* cls = new classname_c(value);
#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;
}