Memory deallocation c++ - c++

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?

Related

c++ Copy Parameter 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;
}

Memory occupation with "this" pointer

Could anyone tell me if the pointer "this" in object of class occupy memory when it was created?
class Temp {
private:
Temp &operator=(const Temp &t) { return *this; }
}
this is the address of the object whose member function is being called, and it doesn't need to be stored anywhere.
It is usually implemented by passing its value as a "hidden" argument to the member functions, so it occupies memory in the same way as any other function argument occupies memory.
The "object-oriented" code
struct A
{
int f() { return this->x; }
int x;
};
int g()
{
A a;
return a.f();
}
will usually be implemented like this "non-object-oriented" code:
struct A
{
int x;
};
int Af(A* self)
{
return self->x;
}
int g()
{
A a;
return Af(&a);
}
No, "this" is already by itself a memory reference and hence it would not occupy more memory than the object already does.

Returning a reference to an element of a class member container

Foo behaves like a circular iterator. Despite me being nervous about it, the code below compiles fine, but creates a run-time error. I receive the error even if I remove the consts from get_current(). Of course, I can return a pointer and it'll work; however, will I get better security returning a reference?
#include <iostream>
#include <array>
#include <memory>
class Foo
{
public:
Foo();
void next();
const int& get_current() const;
private:
std::array<std::unique_ptr<int>, 3> arr_;
unsigned i_;
};
Foo::Foo() : i_(0)
{
arr_[0] = std::unique_ptr<int>(new int(5));
arr_[1] = std::unique_ptr<int>(new int(6));
arr_[2] = std::unique_ptr<int>(new int(7));
}
void Foo::next()
{
++i_;
i_ %= 3;
}
const int& Foo::get_current() const
{
return *arr_[i_];
}
int main()
{
Foo foo;
int* p;
*p = foo.get_current();
//do something with p
std::cout << *p << std::endl;
foo.next();
*p = foo.get_current();
//do something with p
std::cout << *p << std::endl;
return 0;
}
int* p;
That's an uninitialised pointer, not pointing to anything. Dereferencing it gives undefined behaviour.
*p = foo.get_current();
That dereferences the invalid pointer. Boom!
Perhaps you want it to point to the array element
p = &foo.get_current();
or perhaps you want a copy of the array element
int n;
n = foo.get_current();
foo.get_current(); may well be returning a const reference, but after that you're attempting to take a value copy of that when assigning to *p.
Assigning to *p is what's causing you trouble as p is uninitialised. That's undefined behaviour and is manifesting itself in your case as a runtime error.
You could use code like const int& p = foo.get_current(); but do be aware that a reference can only be bound once, so you'll have to be careful with scoping.
Or, you could use std::shared_ptr<int> and make that the return type of get_current(), and strip your code entirely of bare pointers.
*p = ... You dereference int* P without having it properly initialized.
Change your code in main to
int p; // Remove *
p = foo.get_current();
//do something with p
std::cout << p << std::endl;
or if you really meant to use a pointer
const int* p;
p = &foo.get_current();
// ^ Take the address

Pointer to pointer assignment isnt working

EDIT: I have fixed the accidental argument typo in func2() to be MyClass* not MyClass.
I have a class like this:
#include "MyClass.h"
class X{
public:
X();
MyClass* m;
func1();
func2(MyClass* m, int x);
private:
}
Source:
#include "X.h"
X::X{
m = null_ptr;
}
X::func1(){
//Pass the un-initialized data member m here...
func2(m, 6);
//When I get to this point m has not been assigned, even though it was passed as a pointer to func2()
}
X::func2(MyClass* old_obj, int x){
//Please forgive the memory management for a second....
MyClass* new_obj = new MyClass(x);
//This should initialise the data member m??????
old_obj = new_obj ;
}
However it doesn't work- am I making a fundamental miss-assumption here? I thought this would work....
To modify a pointer from function parameter, you need to modify original pointer not it's copy.
func2(MyClass*& m, int x);
// ^

Returning int, int* and int& from a function

I just wanted to clarify something, imagine we have the function signature:
1) int* X(){}
2) int Y(){}
3) int& Z(){}
I am trying to work out the exhaustive possibilities of types of values I can return for the above. The below show possible implementations for the above function bodies:
1)
int* X(){
int* b = new int(6);
return b;
}
2)
int Y(){
int b = 6;
return b;
}
or
int Y(){
int* b = new int(6);
return *b;
}
EDIT: 2) not good because of memory leak if b isn't deleted.
3)
int& Z(){
int b = 6;
return b;
}
EDIT: 3) not good because b will go out of scope once function returns.
Is there anything I have missed out which could be returned from any of the above 3 function signatures? Getting a bit more adventurous, what about:
int* X(){
int b = 6;
return reinterpret_cast<b>;
}
and
int X(){
int* b = new int(6);
return reinterpret_cast<b>;
}
? (My understanding of reinterpret_cast may be wrong...)
int Y(){
int* b = new int(6);
return b*;
}
This has a syntax error. To dereference b, you would do *b. Nonetheless, this is a very bad implementation because it leaks memory. The dynamically allocated int will never be destroyed.
int& Z(){
int b = 6;
return b;
}
This is also bad because you are returning a reference to a local variable. The local variable b will be destroyed when the function returns and you'll be left with a reference to a non-existent object.
int* X(){}
when you have to return address which is pointing to integer
int Y(){}
for returning simple integer
int& Z(){}
this is something different,
you don't have any argument in Z() thus it is useless.
It must be like
int& Z(int &a)
{
//code body
return (a);
}
and return this to reference variable