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;
}
Related
#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;
}
I got a situation where I have a class B having a protected array of A*. I have an another function A* func() which returns pointers to A objects stored in some other container. (for example std::map<int,A*> or A* arr[]).
For example the following implementation:
#include <iostream>
using namespace std;
class A {
public:
A(int _x): x(_x){};
int x;
};
class B{
public:
B() {
this->arr[0] = new A(1);
this->arr[1] = new A(2);
}
// use idx to index in to the internal array and return A*
A*& operator[](int idx); // return reference to pointer to avoid not a lvalue error
private:
// class B has this private array of A*
A* arr[2];
};
A*& B::operator[](int idx) {
return this->arr[idx]; // 0<=idx<=1
}
A* arr[2];
A* func(int x) {
return arr[x]; // 0<=idx<=1
}
int main() {
arr[0] = new A(12);
arr[1] = new A(14);
B b;
b[1] = func(1); // assign a new value
cout << b[1]->x << endl; // prints 14
}
// memory leaks of this program can be removed using `std::shared_ptr<A>` in the place of `A*`.
In this example, operator[]() returns a reference to a pointer, because returning pointer becomes rvalue and I will not be able to assign value to it (i.e. b[1] = func(1)).
My question is, is this reference to pointer returning recommended (other ways to achieve this )? or is this perfectly fine with raw pointers as well as with shared_ptr?
Thank You!
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
I obviously misunderstood something using delete.
Why is this program filling up my memory?
void f(int* x){
x = new int[42];
}
int main(){
while(true){
int* x;
f(x);
delete[] x;
}
return 0;
}
How can I free the memory I allocated in f from inside the main function?
You are not actually modifying the x variable in the outer function.
To do that, you have either to rely on the returned value of f:
int* f(){
return new int[42];
}
int main(){
while(true){
int* x = f();
delete[] x;
}
return 0;
}
Or to pass the variable x by reference:
void f(int*& x){
x = new int[42];
}
int main(){
while(true){
int* x;
f(x);
delete[] x;
}
return 0;
}
Or to use a pointer to pointer as an argument to f:
void f(int** x){
*x = new int[42];
}
int main(){
while(true){
int* x;
f(&x);
delete[] x;
}
return 0;
}
And so on...
There are memory leaks in the function
void f(int* x){
x = new int[42];
}
You allocate memory but never free it. Function parameters are local variables of the function. The function deals with a copy of the original pointer. Any changes of the copy do not influence on the original argument.
And mpreover the program has undefined behaviour because pointer x is not initialized.
int main(){
while(true){
int* x;
^^^^^^
f(x);
delete[] x;
}
return 0;
}
You need to pass the original pointer by reference. So the function should be defined like
void f(int* &x){
x = new int[42];
}
and called like
f(x);
or defined like
void f(int* *x){
*x = new int[42];
}
and called like
f( &x );
Pass the parameter by reference. You're passing it by value.
So what you might want to do is consider constructing a functor/class/struct that uses RAII...
By this I mean how the standard library handles a lot of allocations.
struct A {
A(){/*allocate mem*/}
~A(){/*deallocate mem*/}
}
For your particular function,
void f(int** x);
is most likely the signature you want. This will allow you to modify the array through the pointer to it. Though... I still recommend not doing this... the reason is what about if you decide to allocate a bunch of arrays? Does the main method take responsibility for deallocating memory?
I tried copying a pointer to another by using a method inside the class and the this pointer as follows. I am giving the entire test code so that it is clear what is going on.
class test {
private:
int x;
public:
void setx(int x);
int getx(void);
void copy(test *temp);
};
void test::setx(int x) {
this->x = x;
}
int test::getx(void) {
return this->x;
}
void test::copy(test *temp) {
this = temp;
}
And I access this method from the main as follows:
int main() {
test a;
a.setx(4);
cout << a.getx()<<endl;
test *b = new test;
b->setx(4);
cout << b->getx()<<endl;
test *c;
c=b;
cout << c->getx()<<endl;
test *d;
d->copy(b);
cout << d->getx()<<endl;
}
However it gives the following error
In member function ‘void test::copy(test*)’:
error: lvalue required as left operand of assignment
All the other method involving the this pointer works fine except for the copying part. Am i doing some elementary mistake in using the this pointer?
You cannot overwrite this. The this pointer is a constant, so you're not allowed to change it. And what would that mean anyway? You can't change the object that you're in. You can change the values within that object, but not the object itself.
You need to copy other objects by value (by what is stored in the object), not by pointer.
Also, you shouldn't have a function called copy; that's what copy constructors and copy assignment operators are for.
You cannot modify the this pointer. You can however modify *this:
void test::copy(test *temp)
{
*this = *temp;
}
Also, you should rename the data member or the parameter, so you don't need this->:
class test
{
int m_x;
public:
void setx(int x)
{
m_x = x;
}
what is test::copy supposed to do?
Clearly you cant assign a different address to your current object. So it is invalid.
if this is supposed to initialize the current object with the values of some other object then it should look like this:
void test::copy(test *temp) {
this->x = temp->getX();
}