#include <iostream>
class TEST
{
public:
int* a = new int;
TEST(int x)
: a(&x)
{
}
~TEST()
{
delete a;
}
};
int main()
{
{
int i = 2;
TEST T(i);
}
std::cin.get();
}
I tried to heap allocate integer in a TEST class and then delete it but
when I'm calling delete a in TEST class destructor I'm getting error in file called delete_scalar.cpp and I have no idea what does it mean and how to fix it. Where's the problem?
TEST(int x)
: a(&x)
{
}
This code is causing undefined behavior. It is making a point at a local int that goes out of scope immediately afterwards, leaving a as a dangling pointer to invalid memory. a is never pointing at dynamic memory (the new expression in the declaration of a is ignored when a is initialized in the constructor's member initialization list). That is why the delete fails later.
To do what you are attempting, you need to either:
move the new into the initialization list, eg:
int* a = nullptr;
TEST(int x)
: a(new int(x))
{
}
Or, if you want to keep using new in the declaration of a, then you can assign the value of that int from inside the constructor's body instead of in its initialization list, eg:
int* a = new int;
TEST(int x)
{
*a = x;
}
Related
When I store a plain int in A and perform a simple get function:
#include <iostream>
class A
{
int p;
public:
void setint(int p_x);
int getint();
};
void A::setint(int p_x) {p = p_x;} // set p (type int)
int A::getint() {return p;} // get p (type int)
int main()
{
A arr_a[5];
arr_a[0].getint();
}
it compiles and exits with code 0. However when I change int to int* and try to do the same:
#include <iostream>
class A
{
int* p;
public:
void setint(int p_x);
int getint();
};
void A::setint(int p_x) {*p = p_x;} // set int pointed to by p (type int)
int A::getint() {return *p;} // get int pointed to by p (type int)
int main()
{
A arr_a[5];
arr_a[0].getint();
}
it compiles fine but exits with code 3221225477. Why is this so and is there still a way I can store pointers in A and store A in arrays?
In your 2nd case A arr_a[5] just create a array that contains 5 A. but
for every A, the pointer is an undefined number (maybe 0x0), so *p is a undefined behavior. You should add A::A() and A::~A() to manage your pointer in your class
just like this:
#include <iostream>
class A
{
int *p;
public:
A();
~A();
void setint(int p_x);
int getint();
};
A::A() : p(new int) {}
A::~A() { delete p; }
void A::setint(int p_x) { *p = p_x; } // set int pointed to by p (type int)
int A::getint() { return *p; } // get int pointed to by p (type int)
int main()
{
A arr_a[5];
arr_a[0].getint();
}
Your program has a serious flaw. Both of your given code snippets (case 1 and case 2 in your question) have undefined behavior. Lets see how it is
Case I: Code Snippet 1
In your code snippet 1, since the data member p is a built in type and you've not initialized it, so p has a garbage value and using(accessing) this value can lead to undefined behavior which is exactly what is happening in your case.
When you wrote:
A arr_a[5];//this creates a 1D array of size 5 having elements of type `A` but the elements are default initialized
arr_a[0].getint();//this result in undefined behavior
The above statement creates a 1D array of size 5 having elements of type A. The problem is that since you have not initialized this array, its elements are default initialized which means that the value of data member p is also default initialized. But since you didn't use in-class initializers for variable p, p has garbage value and this leads to undefined behavior.
You can confirm this by looking at the output here.
Solution to Case I
You can solve this by initializing the data member p using in-class initializer as shown below:
#include <iostream>
class A
{
int p = 0;//USE IN-CLASS INITIALIZER
public:
void setint(int p_x);
int getint();
};
void A::setint(int p_x) {p = p_x;} // set p (type int)
int A::getint() {return p;} // get p (type int)
int main()
{
A arr_a[5];
std::cout<<arr_a[0].getint();//now ok because we have initilaized p
}
Case II: Code Snippet 2
In this case the only difference is that now the data member p is a pointer to int that is int*. Similar to last case the pointer variable has a garbage value which can lead to undefined behavior if you try to use it as you did inside your main function by writing:
A arr_a[5];//create a 1D array of objects `A` but the elements(A objects) are default initialized
arr_a[0].getint();//this result in undefined behavior
Solution to Case II
You can solve this by initializing the data member p using in-class initializer as shown below:
#include <iostream>
class A
{
int* p = nullptr;//USE IN-CLASS INITIALIZER
public:
void setint(int p_x);
int getint();
//other members like constructor and destructor to allocate and deallocate memory
//so that getint and setint doesn't dereference nullptr
};
void A::setint(int p_x)
{ if(p!=nullptr)// add a check here to see p isn't null
{
*p = p_x;
}
else
{
std::cout<<"WARNING: Dereferencing a nullptr can lead to UB";
}
}
int A::getint() // add a check here to see p isn't null
{ if(p!= nullptr)
{
std::cout<<"yes"<<std::endl;
return *p;
}
else
{
std::cout<<"WARNING: Dereferencing a nullptr can lead to UB";
return -1;
}
}
int main()
{
A arr_a[5];
arr_a[0].getint();//now ok(assuming `p` isn't nullptr) because we have initilaized p
}
Summary
Both of the code snippets that you gave have undefined behavior. You can solve both of them by using in-class initilaizers to initialize data member p to a default value.
I want to specify the value pointed to by the parameter after dynamic memory allocation.
But I get an error. How can I solve this?
class Point
{
private:
int *x;
public:
Point(int *a)
{
x=int new;
x=a;
}
~Point()
{
if(x)
delete x;
}
void print()
{
cout<<x;
}
};
int main()
{
int c=2;
Point p(&c);
p.print();
return 0;
}
The error is just a small typo: you have to write new int instead of int new. However, your code has a logic error, and that's this line:
x = a;
As x and a are both pointer types, you assign the pointer - and not the value it points to - to x. This way, the original value of x - the integer which was just allocated - is lost, and in the destructor, you're going to delete a! To fix this, you have to assign the value a points to to the integer x points to. This is done with the dereference operator:
*x = *a;
Furthermore, use the dereference operator in print():
cout << *x;
How about
explicit Point(int a)
{
x=new int(a);
}
~Point()
{
delete x;
}
and then Point p(c); in main.
The ctor is explicit in order to avoid surprising implicit conversions. Passing an int rather than a pointer to int is safer - no need for a pointer check and no risk of crashing if you don't check and pass in a NULL pointer. Avoid unnecessary complexity when you can. Also there is no need to check for a NULL pointer when calling delete.
As it stands this code also has problems with the ownership of x.
For instance, if you have
int main()
{
int c = 2;
Point p(&c);
p.print();
Point p2(p); // copy added here
}
Then there will be a double delete of x - a serious error that could cause heap corruption and a crash.
I appreciate that you may be using dynamic memory allocation as a learning exercise, but it would make the code simpler, faster and safer to not use it. Just make x an int. Then you don't need a destructor.
the syntax int new is wrong it should be new int
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
class Point
{
private:
int* x;
public:
Point(int* a)
{
x = new int;
*x = *a;
}
~Point()
{
if (x)
delete x;
}
void print()
{
cout << x;
}
};
int main()
{
int c = 2;
Point p(&c);
p.print();
return 0;
}
I want to know is it okay if i will use following method? There is no syntax errors and any warnings but i want to know is there any memory problems?
#include <iostream>
using namespace std;
class test {
int* x;
public:
test(int *n) { this->x = new int(*n); }
inline int get() { return *x; }
~test() { delete x; }
};
int main(void) {
while(1){
test a(new int(3));
cout << a.get() << endl;
}
return 0;
}
You have 2 issues in your code:
your class violates rule of three/five/zero
you are leaking memory when create a
In this code:
test a(new int(3));
you dynamically allocate int with value 3 and pass to a ctor which uses value and creates it's own dynamically allocated int. After that this memory is leaked. If you want to pass dynamically allocated data to a class use a smart pointer:
class test {
std::unique_ptr<int> x;
public:
test(std::unique_ptr<int> n) : x( std::move( n ) ) { }
int get() const { return *x; }
};
int main()
{
x a( std::make_unique<int>( 3 ) ); // since c++14
x a( std::unique_ptr<int>( new int(3) ) ); // before c++14
...
}
and you do not need to implement dtor explicitly, you do not violate the rule and it is safe to pass dynamically allocated data to ctor.
Note: I assumed you used int as example and you would understand that dynamically allocate one int is useless, you should just store it by value.
You are violating the rule of 3 (5 since c++11). It means that since you defined the destructor you should define the copy/move constructor/operation.
With your implementation, the copy/move constructor/operation are wrong. When you copy your object, it will do a shallow copy of your pointer and will delete it therefore you will have a double delete. When you move it, you will delete a pointer you didn't allocated.
Bonus point: your inline is useless
#include <iostream>
class Object {
public:
int x;
Object() { }
Object(int x) {
this->x = x;
}
};
class SomeClass {
public:
Object array[10];
int n;
SomeClass() { n = 0; }
void insert(Object o) {
array[n++] = o;
}
};
int main() {
SomeClass s;
Object test = Object(4);
s.insert(test);
return 0;
}
I have this example where I pre-allocate an array of objects in SomeClass and then in some other method, main in this example, I create another object and add it to the array in SomeClass
One thing I think I should do is to switch from array[10] to an array of pointers so that I only create objects when I really need to.
But my question is what happens to the memory originally allocated for array[0] when I do "array[n++] = o" replacing it by the new object "o"? does it get de-allocated?
No, nothing happens. The object's assignment operator gets invoked, to replace the object.
For this simple class, the assignment operator is the default operator which, more or less, copies each of the object's members, one at a time.
(No need to get into move operators, etc..., just yet)
class A {
public: int i;
};
A *a = new A();
How to get the address of a->i? I tried &a->i and also &(a->i) but those generate compile time errors:
"left of '.i' must have class/struct/union type"
You have not provided the same code you tried to compile. Always copy and paste. The tells in your code are that you don't have a syntactically correct class declaration or variable declaration, and that your error message talks about ".i" when you've claimed you've only used a->i. Here's working code:
#include <stdio.h>
class A {
public:
int i;
};
int main() {
A* a = new A();
int* i = &a->i;
printf("a: %p\na->i: %p\n", a, i);
return 0;
}
Ultimately, the syntax you say you tried for getting the address of the member was correct. The syntax the error message says you tried was a.i. That doesn't work, and for the reason the error message gave. The variable a is not a class, struct, or union type. Rather, it's a pointer to one of those types. You need to dereference the pointer to get at the member.
When I run it, I get this:
$ ./a.out
a: 40748
a->i: 40748
The addresses are the same because A is a simple class, so this output is to be expected. The first member is frequently placed at the very start of a class's memory. Add a second member variable to the class and get its address; you should see different values then.
In c++:
class A {
public: // note colon after public
int i;
}; // note semicolon after bracket
A *a = new A(); // note *a not a*
to print:
cout << ios::hex << &a->i << endl;
For me this seems to work ok.
&a->i should work. In your case since the class just has one public integer both the address of a and i will be the same.
You're on the right track, but from the compile error you mention, it sounds like you were typing "&a.i"
class A
{
public:
int i;
};
...
A *a = new A();
int *i = &a->i;
This code appears to compile?
class A {
public:
int i;
};
int main() {
A *a = new A();
int *x = &a->i;
return 0;
}
The following works for me using g++
class A
{
public:
int m_i;
};
int
main()
{
A* a = new A();
int* i_ptr = &(a->m_i);
return 0;
}
I am guessing you mean A* a = ... and not A a* = ...