C++ delete class variable from function - c++

class Foo {
// some codes
}
class Bar {
// Constructor, Destructor
vector<Foo*> fooVector;
Foo* getFoo(long index)
{
return fooVector[index];
}
long addFoo(Foo* foo)
{
fooVector.push_back(foo);
return fooVector.size() - 1;
}
void removeFoo(long index)
{
delete fooVector[index];
}
}
This is my codes.
But I want to change removeFoo like
void removeFoo(long index)
{
Foo* foo = getFoo(index);
delete foo;
}
Is it right? I can't sure about this.
In my thought, It may delete foo variable.
Please tell me whether it is right or not.

If the memory for the pointer was allocated by new then yes that's how you free it. However, that won't remove the pointer from the vector, so afterwards your vector have an entry that no longer point to valid memory. You need to erase it from the vector.
Also note that in modern C++ there is seldom a need to use pointers anymore, except for polymorphism really. If you don't have pointers, you don't have to worry about freeing memory or stray pointers.

Using such method you are bypassing most of the benefits you gained from using vector. When removing elements by delete (which is valid in the case you described) you will rubbish your fooVector with non-valid data pointers to some undeclared/invalid memory areas.
It would be handy if, in addition, you showed us how you actually create fooVector elements.
In my opinion, both ways that you presented are valid in C++, but they will lead to hard-to-rely-on results and rubbish in your vector.

Related

Conditional declaration of objects inherting from a common base class to pass a reference to one of them

Say I have two classes inheriting from a common base, such as
class Thing{
public:
virtual void f()=0;
};
class Thing_variant_a: public Thing{
public:
void f(){
std::cout<<"I am (a)"<<std::endl;
}
};
class Thing_variant_b: public Thing{
public:
void f(){
std::cout<<"I am (b)"<<std::endl;
}
};
And a function taking a reference to a Thing object as an argument.
void function(Thing& t){
t.f();
}
Depending on conditions I would like to call function with either a thing_a or thing_b (and possibly extend this at some point adding another possibility of thing_c)
I know I can do this using a pointer
Thing *t = nullptr;
if(condition_a){
t = new Thing_variant_a();
} else if(condition_b){
t = new Thing_variant_b();
}
function(*t);
However, I would like to know if there is a better way, that
does not allocate heap memory
does not require me to take care of deleting t at some point (probably smart pointers, but I don't know much about those)
ensures I always pass a valid Thing reference to function (there might be more conditionals in a complicated structure than in this minimal example) I could do if(t){ function(*t);}else{/*handle error*/}), but it seems like there should be a more elegant solution.
If not all of the above are possible any combination of those?
This sounds very much like an XY problem. There is probably a different solution to your problem entirely.
C++ is a statically-typed language; that means types used in a given code path are fixed at compile-time. Dynamic types (types known at run time) are normally allocated via the heap or all-at-once and then selected at run time.
So not much is possible in your case as you've noticed..
You could for example just have two different code paths:
if (condition_a) {
Thing_variant_a a;
function(a);
} else if (condition_b) {
Thing_variant_a b;
function(b);
}
Preallocate the types:
Thing_variant_a a;
Thing_variant_a b;
if (condition_a) {
function(a);
} else if (condition_b) {
function(b);
}
Or use a template:
template<typename T>
void do_something() {
T t;
function(t);
}
// somewhere else in the code ...
do_something<Thing_variant_a>();
// or ...
do_something<Thing_variant_b>();
Here's a way using dynamic memory and unique_ptr:
std::unique_ptr<Thing> t;
if (condition_a) {
t = std::make_unique<Thing_variant_a>();
} else if (condition_b) {
t = std::make_unique<Thing_variant_b>();
}
function(*t);
// t is delete'd automatically at end of scope...
And by the way, a function like int f(){...} should return some int value.
Here is a way to do it without using the heap or pointers:
Thing_variant_a thingA;
Thing_variant_b thingB;
if(condition_a){
function(thingA);
} else if(condition_b){
function(thingB);
}
If you want, you reduce it to a single call via the ternary operator:
Thing_variant_a thingA;
Thing_variant_b thingB;
function(condition_a ? static_cast<Thing &>(thingA) : static_cast<Thing &>(thingB));
As far as references go, references in C++ are required to be always be non-NULL -- so if you try to dereference a NULL pointer (e.g. by calling function(*t) when t==NULL) you've already invoked undefined behavior and are doomed; there is nothing the code inside function() can do to save you. So if there is any change that your pointer is NULL, you must check for that before dereferencing it.
I'll try to answer each of your questions
does not allocate heap memory
Unfortunately c++ only supports polymorphism using pointers. I guess the problem you would face here is fragmented memory (meaning that your pointers are everywhere in the heap). The best way to handle that is to allocate the memory using a memory pool.
You could use an std::variant but you will still need to test for the currently available type in the variant.
does not require me to take care of deleting t at some point (probably smart pointers, but I don't know much about those)
You could use a std::unique_ptr which will basically called the destructor when no one holds that pointer anymore.
ensures I always pass a valid Thing reference to function (there might be more conditionals in a complicated structure than in this minimal example) I could do if(t){ function(*t);}else{/handle error/}), but it seems like there should be a more elegant solution.
If you use pointers your could just check for the nullptr as you are doing right now. I'm not sure what you are meaning by valid reference as a reference always points toward something and cannot be empty.

Memory Leaks without calling clear() on C++ STL container objects

Suppose that I have a class Foo defined as follows.
If I don't have bars.clear() in ~Foo(), will this result in memory leaks?
I was wondering about this because bars is an object field ( not a pointer field ) so when ~Foo() is called, the destructor of std::vector should be automatically called so I was wondering whether the destructor of std::vector will transparently call .clear() or not.
class Foo
{
private:
std::vector<Bar*> bars;//object field
...
};
Foo::~Foo
{
//bars.clear();
}
std::vector::clear() delete the objects within std::vector and change its std::vector::size() to zero. If you create std::vector, RAII will take care resource release process but you have to wait until reach the out of scope of the vector. If before going out of scope, you need to clean up your vector you can use std::vector::clear().
But in your special case you are keeping pointer to objects inside std::vector, so RAII do delete the pointer but ignores the objects pointing to the pointer. So you have to do your own clean up for the objects pointing to the pointer either before going out of scope and RAII become active or before calling std::vector::clear()
clear() just resets the vector to size 0. It does not delete anything, if the Bar* in the vector bars need to be deleted, you have to do it yourself.
If you hope to protect yourself against memory leaks by calling the clear() method, then I have to disappoint you. If you use a vector with pointers you need to do something like this:
std::vector<Bar*> bars;
bars.push_back(new Bar());
// some work with bars
// ....
// end of bars usage:
// (probably inside ~Foo() )
for(int i=0; i<bars.size(); i++) delete bars[i];
Depending on your level of experience and your specific use-case you might be better of using:
std::vector<Bar> bars;
If you want to know whether the std::vector<...>::clear() method is called from within the destructor of the vector, then the answer is: Maybe but not necessarily and it really doesn't matter anyway.
If you're really curious, you might be able to check, what a destructor of a container class does by looking at the header file for the vector container template. If and how much implementation details of std library objects are visible to the user is highly dependant on the system you're running with. At work I happen to work on Solaris 10 machines. The std lib on those machines is an implementation from Hewlett Packard anno 1994, where a lot of the actual code used by the vector template is still visible:
~vector ()
{
__destroy(__start, __finish);
__value_alloc_type va(__end_of_storage);
va.deallocate(__start,__end_of_storage.data()-__start);
}
void clear()
{
erase(begin(),end());
}
iterator erase (iterator first, iterator last)
{
iterator i = copy(last, end(), first);
iterator tmp = __finish;
__finish = __finish - (last - first);
__destroy(i, tmp);
return first;
}

C++ property declaration [duplicate]

This question already has answers here:
Why use pointers? [closed]
(17 answers)
Closed 9 years ago.
I'm diving into C++ coming from the worlds of Objective-C and Java. Java gave me all the OOP knowledge I have and Objective-C taught me about manual memory management. While adapting to C++ is easy (the language definitely does not deserve the reputation it has) I am confused about one thing:
I can declare a property as string my_string or string *my_string. I know I need to delete the second, but what's the advantage in declaring it as a pointer?
In most situations there is no benefit at all to use the pointer variant.
One reason to use this is if you want the member to survive the destruction of the object (if you do not delete it in the destructor). However this necessity is usually enforced by bad design, so I'd try to avoid this.
Another reason (and the more probable one) is, if you want the member to optionally be undefined (that is you initialize the member to NULL/nullptr(c++11) in the constructor and each read access checks if the pointer is still NULL or actually points to a value). This way you can postpone intialization. However even in this case I'd suggest using smart pointers (std::shared_ptr in c++11 or boost::shared_ptr in c++98) or boost::optional...
People have answered almost completely, but I'd add this reason: while declaring a variable as a pointer is useless, it comes in handy if it's a big structure and you have to pass it as a parameter to many functions, like a recursive algorithm.
strcut sMyStruct
{
// A lot of members
}
// Somewhere in your code
sMyStruct foo;
RecursiveOperation( &foo );
// Somewhere else if you want foo to don't be modified.
void RecursiveOperation( const sMyStruct *pFoo )
{
}
// or...
void RecursiveOperation( sMyStruct *pFoo )
{
}
In this case, having *pFoo makes your code faster and cheaper, even if you could use & to pass the reference having some more safety but slightly less speed.
Obviously I may be wrong but that's what jobmates teached me.
I know I need to delete the second
A pointer does not necessarily mean that any dynamically allocation is involved, at all. Therefore a pointer does not automatically need to be deleted.
What's the advantage in declaring it as a pointer?
As a rule of thumb you should always use automatic allocated memory (~ stack). If you'll ever feel the need to use dynamically allocated memory (for lack of space in the stack for example), you'll know. Dynamically allocated memory can also be used to manually control the lifetime of an object, but that's dangerous most of the time: that's why we have smart pointers like std::unique_ptr and std::shared_ptr.
In this particular case, unless you really need to have a pointer to an std::string as a reference (that can be nullptr) to a string, I can't see the purpose of it. Most std::string's implementations already store the char array dynamically.
In C++ you can store variables on stack or on heap, when you manage pointers usually you are on the heap and you need manually memory managment.
Small objects are good for stack, large object like a very huge string is not good for stack and can cause a stackoverflow (stack is quite small, see you compiler to see stack space ).
std::string are not huge object on the stack because they internally manage the pointers on the heap. Declaring a string as a pointer means that you usually need that string to refering to something else.
What can I suggest to you is to avoid raw pointers always. Prefer std::unique_ptr or std::shared_ptr.
Nothing. In C++, use values instead of pointers unless required. Heck, you can get away with references instead of pointers in most cases as well (like function calls).
There really is no sense in using std::string*.
The only time A* makes sense, or is useful at all, is when there are subclasses of A which you want to assign to this base class pointer. An example, with the classical shape
#include <iostream>
#include <memory>
#include <vector>
class shape
{
public:
virtual ~shape() {}; // required to properly be able to delete base class pointers
virtual bool isRound() const = 0;
virtual const char* name() const = 0;
};
class rectangle : public shape
{
public:
bool isRound() const { return false; }
const char* name() const { return "rectangle"; }
};
class circle : public shape
{
bool isRound() const { return true; }
const char* name() const { return "circle"; }
};
class square : public rectangle
{
const char* name() const { return "square"; }
};
int main()
{
std::vector<std::unique_ptr<shape>> shapes;
shapes.emplace_back(new square());
shapes.emplace_back(new circle());
shapes.emplace_back(new rectangle());
for(const auto& s : shapes)
{
if(s->isRound())
std::cout << s->name() << " is round.\n";
else
std::cout << s->name() << " is not round.\n";
}
}
Live demo
Here, the vector of pointers is only an example, it might be a member of a class or anything else really.
Note I used std::unique_ptr<shape> instead of shape*. Learn about smart pointers. Fast.
You have to understand the fact the pointer is some thing that holds the address to a memory location .It can hold the address from stack as well as from heap

Should I delete local pointers in functions? (C++)

A question:
Should I delete pointers which are fetched in functions (not created, just fetched)? Example:
#include <SomeObject>
#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } }
class DraftObject
{
public:
DraftObject() : _x(0) {}
~DraftObject(){}
int CalculateSomething()
{
AnotherObject* aObj = SomeObject::getInstance()->getAObjPointer();
/* Do some calculations and etc... */
_x += aObj->GetSomeIntValue();
SAFE_DELETE(aObj) // <-- Would you recomend this here?
return _x;
}
protected:
int _x;
};
The aObj would be re-used in other cases as well in the SomeObject instance. I could go on and always call SomeObject::getInstance()->getAObjPointer() for everything I need it for, but SomeObject::getInstance()->getAObjPointer()->GetSomeIntValue() is not as readable as aObj->GetSomeIntValue() in my personal opinion.
I know that I would not need to worry if I used something from boost (shared_ptr, weak_ptr or even auto_ptr), but I am more curious about the way this works. Will not deleting the pointer create a memory leak situation or will the deletion of the pointer delete it from the memory so that it will be gone in other scopes (the instance object as well as anywhere else it might be used) ?
Any thoughts?
Cheers.
It depends.
If SomeObject::getInstance()->getAObjPointer(); returns a different object each call, probably yes. Otherwise, no. This should be documented.
Also, your "safe delete":
#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } }
is utterly useless. And ugly. If I saw this in code, I'd go and make fun of the programmer who wrote it. If p is NULL, the delete is safe.
No, do not use delete because that will deallocate the memory for the object and you will not be able to use it later.
It should be documented in the API.
Some libraries are returning pointers which SHOULD NOT be deleted by the users, because they are also kept in internal data structures. Others are creating pointers which should be deleted by the user.
Assuming that you have actually wrote yourself this class and function, you probably want to delete the pointer at the end of the function if you don't use use this instance anywhere else (including in internals functions).

Prototype for function that allocates memory on the heap (C/C++)

I'm fairly new to C++ so this is probably somewhat of a beginner question. It regards the "proper" style for doing something I suspect to be rather common.
I'm writing a function that, in performing its duties, allocates memory on the heap for use by the caller. I'm curious about what a good prototype for this function should look like. Right now I've got:
int f(char** buffer);
To use it, I would write:
char* data;
int data_length = f(&data);
// ...
delete[] data;
However, the fact that I'm passing a pointer to a pointer tips me off that I'm probably doing this the wrong way.
Anyone care to enlighten me?
In C, that would have been more or less legal.
In C++, functions typically shouldn't do that. You should try to use RAII to guarantee memory doesn't get leaked.
And now you might say "how would it leak memory, I call delete[] just there!", but what if an exception is thrown at the // ... lines?
Depending on what exactly the functions are meant to do, you have several options to consider. One obvious one is to replace the array with a vector:
std::vector<char> f();
std::vector<char> data = f();
int data_length = data.size();
// ...
//delete[] data;
and now we no longer need to explicitly delete, because the vector is allocated on the stack, and its destructor is called when it goes out of scope.
I should mention, in response to comments, that the above implies a copy of the vector, which could potentially be expensive. Most compilers will, if the f function is not too complex, optimize that copy away so this will be fine. (and if the function isn't called too often, the overhead won't matter anyway). But if that doesn't happen, you could instead pass an empty array to the f function by reference, and have f store its data in that instead of returning a new vector.
If the performance of returning a copy is unacceptable, another alternative would be to decouple the choice of container entirely, and use iterators instead:
// definition of f
template <typename iter>
void f(iter out);
// use of f
std::vector<char> vec;
f(std::back_inserter(vec));
Now the usual iterator operations can be used (*out to reference or write to the current element, and ++out to move the iterator forward to the next element) -- and more importantly, all the standard algorithms will now work. You could use std::copy to copy the data to the iterator, for example. This is the approach usually chosen by the standard library (ie. it is a good idea;)) when a function has to return a sequence of data.
Another option would be to make your own object taking responsibility for the allocation/deallocation:
struct f { // simplified for the sake of example. In the real world, it should be given a proper copy constructor + assignment operator, or they should be made inaccessible to avoid copying the object
f(){
// do whatever the f function was originally meant to do here
size = ???
data = new char[size];
}
~f() { delete[] data; }
int size;
char* data;
};
f data;
int data_length = data.size;
// ...
//delete[] data;
And again we no longer need to explicitly delete because the allocation is managed by an object on the stack. The latter is obviously more work, and there's more room for errors, so if the standard vector class (or other standard library components) do the job, prefer them. This example is only if you need something customized to your situation.
The general rule of thumb in C++ is that "if you're writing a delete or delete[] outside a RAII object, you're doing it wrong. If you're writing a new or `new[] outside a RAII object, you're doing it wrong, unless the result is immediately passed to a smart pointer"
In 'proper' C++ you would return an object that contains the memory allocation somewhere inside of it. Something like a std::vector.
Your function should not return a naked pointer to some memory. The pointer, after all, can be copied. Then you have the ownership problem: Who actually owns the memory and should delete it? You also have the problem that a naked pointer might point to a single object on the stack, on the heap, or to a static object. It could also point to an array at these places. Given that all you return is a pointer, how are users supposed to know?
What you should do instead is to return an object that manages its resource in an appropriate way. (Look up RAII.) Give the fact that the resource in this case is an array of char, either a std::string or a std::vector seem to be best:
int f(std::vector<char>& buffer);
std::vector<char> buffer;
int result = f(buffer);
Why not do the same way as malloc() - void* malloc( size_t numberOfBytes )? This way the number of bytes is the input parameter and the allocated block address is the return value.
UPD:
In comments you say that f() basically performs some action besides allocating memory. In this case using std::vector is a much better way.
void f( std::vector<char>& buffer )
{
buffer.clear();
// generate data and add it to the vector
}
the caller will just pass an allocated vector:
std::vector buffer;
f( buffer );
//f.size() now will return the number of elements to work with
Pass the pointer by reference...
int f(char* &buffer)
However you may wish to consider using reference counted pointers such as boost::shared_array to manage the memory if you are just starting this out.
e.g.
int f(boost::shared_array<char> &buffer)
Use RAII (Resource Acquisition Is Initialization) design pattern.
http://en.wikipedia.org/wiki/RAII
Understanding the meaning of the term and the concept - RAII (Resource Acquisition is Initialization)
Just return the pointer:
char * f() {
return new char[100];
}
Having said that, you probably do not need to mess with explicit allocation like this - instead of arrays of char, use std::string or std::vector<char> instead.
If all f() does with the buffer is to return it (and its length), let it just return the length, and have the caller new it. If f() also does something with the buffer, then do as polyglot suggeted.
Of course, there may be a better design for the problem you want to solve, but for us to suggest anything would require that you provide more context.
The proper style is probably not to use a char* but a std::vector or a std::string depending on what you are using char* for.
About the problem of passing a parameter to be modified, instead of passing a pointer, pass a reference. In your case:
int f(char*&);
and if you follow the first advice:
int f(std::string&);
or
int f(std::vector<char>&);
Actually, the smart thing to do would be to put that pointer in a class. That way you have better control over its destruction, and the interface is much less confusing to the user.
class Cookie {
public:
Cookie () : pointer (new char[100]) {};
~Cookie () {
delete[] pointer;
}
private:
char * pointer;
// Prevent copying. Otherwise we have to make these "smart" to prevent
// destruction issues.
Cookie(const Cookie&);
Cookie& operator=(const Cookie&);
};
Provided that f does a new[] to match, it will work, but it's not very idiomatic.
Assuming that f fills in the data and is not just a malloc()-alike you would be better wrapping the allocation up as a std::vector<char>
void f(std::vector<char> &buffer)
{
// compute length
int len = ...
std::vector<char> data(len);
// fill in data
...
buffer.swap(data);
}
EDIT -- remove the spurious * from the signature
I guess you are trying to allocate a one dimensional array. If so, you don't need to pass a pointer to pointer.
int f(char* &buffer)
should be sufficient. And the usage scenario would be:
char* data;
int data_length = f(data);
// ...
delete[] data;