Call delete on std::vector - c++11

Do I have to call delete on the destructor of a class that uses std::vectors ?
If not, why?
For example:
Test.h:
class Test
{
private:
// Signal buffer for RAW signal and Moving Average
std::vector<double> BUFFER; // Sensor signal buffer
...
}
Test.cpp:
#include "Test.h"
Test::~Test()
{
// no delete for std:vector as they use STD memory allocation ???
}
Test::Test()
{
BUFFER.reserve(100); // Who is going to free this memory?
}
Thanks

No you do not need to explicitly destroy or delete it. The vector is held by value in your class, so will be destroyed automatically, and the data inside the vector will be deleted by the vector's own destructor.
The term for all this is RAII, and it works really well.

No, you don't. You only use delete to match a use of new. Since (in this case) you used auto storage class, the vector will be deleted automatically when the Test that owns it is destroyed.

Related

Attempting to store references to c++ vectors returned by reference still giving me copies

Back in '98 I converted my chemical model from objective-c to c++ after replacing my old NeXT, but I didn't really get a chance to learn c++. I'm now rewriting the code into modern c++, which means learning to use containers, smart pointers, and templates.
I need to parse output variables only once up front, rather than at each time step, so I originally produced a pointer array of output variable pointers (float ***outVars). I could run through the list of pointers after each time interval, and since outVars pointed to the original data, they would always provide the current state of the model.
I'm changing code from matrices of naked pointers to matrices of vectors. I haven't been able to return anything but copies of vectors, rather than references to the original vectors. I don't want to modify the vectors, I just need direct read access.
I can't believe I haven't found my answer online yet. Most that I've found online has simply said use std::vector<float> & to return by reference, but clearly that isn't working.
I saw one note that assigning a reference to a non-reference value (I assume they meant variable) will make it copy, so I tried fvec2D &outVar2D; (see the header file below).
I've tried with and without const, no difference.
I've tried returning vector.data(), but assigning it to a new vector was also copying. Maintaining pointers to .data() memory blocks seems be a very bad idea, if I need to resize the original vector.
I've tried wrapping the vector in std::shared_ptr, but found I'd need to wrap each dimension vector in a shared_ptr, which got overly cumbersome real fast.
I saw one suggestion to return vector::iterators. I haven't managed to get that to work yet. Maybe having 2D data is getting in the way of that. I'm still trying to get that to run without crashing when I examine the iterator.
I don't know if using a 1D array would solve this, but calculating every index reference for millions of calls seems suboptimal.
I considered using std::array too but vectors seemed the simplest conversion. Perhaps I should rethink that.
If anyone has any suggestions for how to do this, I'd very much appreciate it.
class chem - manages original matrix concentration
class chem
{
public:
typedef std::vector<float> fvec1D;
typedef std::vector<std::vector<float> > fvec2D;
chem(int xstep, int zstep) : concentration(xstep, fvec1D(zstep, 1.5)) {}
...
const fvec2D &getConc() const { return concentration; }
const fvec1D &getConc(int x) const {return concentration[x]; }
private:
fvec2D concentration;
};
class model - needs read access to chem::concentration
class model
{
public:
typedef std::vector<float> fvec1D;
typedef std::vector<std::vector<float> > fvec2D;
...
private:
fvec2D null2D {{0.0}};
fvec1D null1D {0.0};
fvec2D &outVar2D;// = null2D; // tried this and at ctor
fvec1D &outVar1D;// = null1D;
std::vector<std::unique_ptr<chem> > chemList;
};
model::model() : outVar2D(null2D), outVar1D(null1D)
{
outVar2D = chemList[0]->getConc(); // or
outVar1D = chemList[0]->getConc(1);
}
void model::plot()
{
for (int z=0; z<numZSteps; ++z) {
std::cout << outVar1D[z];
std::cout << outVar2D[1][z];
}
}
void model::run()
{
plot(); // produces init concentration of 1.5 at each z
chemList[0]->changeConc(); // Changes values in concentration
plot(); // STILL produces init conc of 1.5 at each z
}
I don't know if answering my own question is appropriate (please let me know). I know this question will be autodeleted, so I thought I'd present the solution I came up with, because I'm still VERY interested in hearing any suggestions of the best way to do this. I'm still so far down the learning curve I know I can't intuitively see c++ programming techniques.
I gathered from comments that what I was trying won't work, so I wrapped my vectors in shared_ptrs, which I know can work. I created some wrapper classes to manage 2 levels of shared_ptr (one for the multidimensional spatial data, and one for the list of output variables). It also keeps the array-type indexing intact as well as defines behavior for operator=.
I have only included the 2D classes here. I have 4 similar classes to handle the 1D and 3D cases as well.
I know what I'm posting is not great. it's not very elegant, requiring 2 classes for each dimensional case (1D, 2D, 3D data). Perhaps I can simplify it using templates. I've only written very elementary templates so far. Since each class decays (using operator[]) to a unique class I'm not sure if a template will help.
I haven't figured out all the const keyword placements yet - I removed them all for now, out of frustration with the compiler complaints. I'll get that down when I can take the time.
I also don't know exactly what sort of behavior I want for copy and move constructors, though I'm pretty sure I need them for vector resize operations, which I just realized I haven't even implemented yet. The important thing for me here was just to get read access to the vectors across classes, such that when the vectors change it is reflected elsewhere without re-parsing my output variables.
#include <memory>
#include <vector>
namespace MDType {
class fpv2D;
typedef std::vector<float> fvec1D;
typedef std::vector<std::vector<float> > fvec2D;
typedef std::vector<std::vector<std::vector<float> > > fvec3D;
typedef std::shared_ptr<fvec1D> fvec1Dptr;
typedef std::shared_ptr<fvec2D> fvec2Dptr;
typedef std::shared_ptr<fvec3D> fvec3Dptr;
typedef std::vector<fpv2D> fvpv2D;
typedef std::shared_ptr<fvpv2D> fvpv2Dptr;
class fpv2D
{
public:
fpv2D(int x=1, int z=1, float fill=0.0) : theArray(new fvec2D(x, fvec1D(z, fill))) {}
fpv2D(const fpv2D &otherT) = default; // Pretty sure this needs to change
fpv2D( fpv2D &&otherT) {theArray = otherT.data(); }
fvec2Dptr &data() { return theArray; }
fvec1D &operator[](int index) {return theArray->data()[index]; }
void operator=( fpv2D& rhs) { theArray = rhs.data(); }
private:
fvec2Dptr theArray;
};
class fpvpv2D
{
public:
fpvpv2D(int index, int x=1, int z=1, float fill=0.0) : theArray(new fvpv2D(index, fpv2D(x, z, fill))) {}
fpvpv2D(const fpvpv2D &otherT) = default; // Pretty sure this needs to change
fpvpv2D( fpvpv2D &&otherT) {theArray = otherT.data(); }
fvpv2Dptr &data() { return theArray; }
fpv2D &operator[](int index) {return theArray->data()[index]; }
void operator=( fpvpv2D& rhs) { theArray = rhs.data(); }
private:
fvpv2Dptr theArray;
};
}
... so ...
MDType::fpv2D conc(numX, numZ, 1.5);
MDType::fpvpv2D outVar2D(numOutVars, numX, numZ);
outVar2D[1] = conc;
cout << outVar2D[1][3][5]; // prints 1.5
conc[3][5] = 12.0;
cout << outVar2D[1][3][5]; // prints 12.0

Problems using a std::map containing a class without copy operator (Gdiplus::Image)

It seems I am trying to fill a std::map with objects that are not copyable, and I have not achieved to do it yet.
General problem
I want to use std::map in order to store some objects of a type called Image (More precisely, it is Gdiplus::Image). I cannot write things like:
map<string, Gdiplus::Image> loadedImages ;
Gdiplus::Image newImage( CString("totoro.png") );
loadedImages.insert(std::pair<string, Gdiplus::Image>( "totoro", newImage ) );
Function "insert" seems to be the problem here. The compiler says:
'Gdiplus::Image::Image' : cannot access private member declared in class 'Gdiplus::Image'
I am not sure that it is the right explaination, but it seems that "Image" lacks of a public method used in function "insert". (Copy operator ? Copy constructor ?).
What I have tried
I tried to use references in the map, but it seems putting references in containers never works. I tried to use raw pointers, but I had got errors when I tried to delete all the images in the destructor. I happened across this other (and quite similar) question and I have begun to care about smart pointers. So now, I am trying, as recommended in the answer, with std::shared_ptr. However, my case is slightly different.
I want to write a function "find" that returns an image. "find" gives the image found in the map if the key (its path) exists, else it loads the image, add it to the map and returns it. So I cannot create a new image inside the parenthesis as I need the pointer.
The only version I came up with, that can compile is:
(Drawer.h)
#include <map>
#include <memory>
#include <Gdiplus.h>
using std::map ;
using std::shared_ptr ;
class CDrawer
{
public:
CDrawer(void);
~CDrawer(void);
void drawImage(string p_pathToPicture)
private:
map<string, shared_ptr<Gdiplus::Image>> m_loadedImages ; // Keep every image in memory instead of loading them each time. Each image has its path as a key.
Gdiplus::Image* findImage(string& p_path); // get the image from the map if the image is already loaded, else load it.
};
(Drawer.cpp) (Constructors and destructors are empty)
void CDrawer::drawImage(string p_pathToImage)
{
// get the bounding rectangle of the image
//...
Gdiplus::Image* l_image = findImage(p_pathToImage);
// Draw the image.
//...
}
Gdiplus::Image* CDrawer::findImage(string& p_pathToImage)
{
auto iterator = m_loadedImages.find(p_pathToImage);
if (iterator == m_loadedImages.end() ) // image not found, so we have not already loaded it
{
shared_ptr<Gdiplus::Image> l_newImage( new Gdiplus::Image( CString( p_pathToImage.c_str()) ) ); // Load the image (I know I have to add error code)
m_loadedImages.insert( std::pair<string, shared_ptr<Gdiplus::Image>>( p_pathToImage, l_newImage ) ); // Add the image to the list
return l_newImage.get() ;
}
else return iterator->second.get() ; // image found, so it is already loaded and we provide the existing one.
}
But it gives the following error during run time, when the destructor of Drawer is called:
Unhandled exception at 0x00C18CEE in MyProgramm.exe: 0xC0000005: Access violation reading location 0x02F36D78
Does someone knows where I am wrong, or if there is a simpler or better solution?

Why does std::vector fill constructor not enable emplacement?

Every now and then I come across a situation when I need to create an array of non-copy-constructible objects. For example:
std::vector<std::thread> thread_pool(NUM_CORES, std::thread(some_function));
That would be convenient. But alas, the std::vector fill constructor doesn't seem to have any support for R-values. It is defined as:
vector(
size_type count,
const T& value,
const Allocator& alloc = Allocator()
);
But it would be extremely convenient to have:
vector(
size_type count,
T&& value,
const Allocator& alloc = Allocator()
);
Then the vector could internally allocate the necessary buffer size, and move-construct each element with placement new.
But... the C++11 standard (and apparently even the C++14 standard) don't provide this capability. So, now - when I have a vector of threads, I have to say:
std::vector<std::unique_ptr<std::thread>> thread_pool(NUM_CORES);
/* now loop over vector and initialize elements one by one */
Is there some reason this ability was left out? Is there some danger? Or some problem that I'm not seeing?
What you propose is not feasible because, by its very nature, moving is the transfer of a state from one object to one other object. You cannot construct N objects by moving state from one to all of them at the same time.
The Stargate universe violated this rule by introducing the ability to open a wormhole to every gate in the galaxy simultaneously, which made no sense at all and really annoyed me. Don't be that guy!
A vector constructor looking like this:
template <typename T>
template <typename Args...>
std::vector<T>::vector(const size_t n, Args&&... args);
…following the emplace model could work, though I worry that it would be easy to get an ambiguous overload thanks to the sheer number of existing constructors for std::vector<T>. I suspect this is why it was not done, besides the fact that it isn't really necessary.
Because, for now, you can workaround it by emplacing one at a time which, regardless, is probably as performant as you can ever hope to get:
std::vector<std::thread> v;
v.reserve(NUM_CORES);
for ( /*...*/ )
v.emplace_back( /*...*/ );

Passing NSTextField Pointer to IOUSBInterfaceInterface182 Callback

I'm doing an asynchronous read from a USB printer. The read works correctly. My trouble is updating a NSTextField from within the callback.
-(IBAction)printTest:(id)sender
{
// Setup... then:
NSLog(#"starting async read: %#", _printerOutput);
NSLog(#"_printerOutput pointer = %p", _printerOutput);
result = (*interface)->ReadPipeAsyncTO(interface,
1,
readBuffer,
numBytesRead,
500,
1000,
USBDeviceReadCompletionCallback,
&(_printerOutput)
);
The callback is defined as:
void USBDeviceReadCompletionCallback(void *refCon, IOReturn result, void *messageArg)
{
NSTextField *printerOutput = (__bridge NSTextField *) messageArg;
NSLog(#"_printerOutput pointer = %p", printerOutput);
}
The pointer loses its value when inside of the callback.
starting async read: <NSTextField: 0x10221dc60>
_printerOutput pointer = 0x10221dc60
_printerOutput pointer = 0x0
I've looked in many places trying to mimic different ways to pass in the pointer. There can be only one correct way. :)
Another variation on the theme: (__bridge void *)(_printerOutput). This doesn't work, either.
I understand that the callback is of type IOAsyncCallback1.
Other URLs of note:
http://www.google.com/search?client=safari&rls=en&q=another+usb+notification+example&ie=UTF-8&oe=UTF-8 and updating UI from a C function in a thread
I presume _printerOutput is an NSTextField*?
First, is there a particular reason why are you passing an NSTextField** into the callback? (Note the ampersand in the last argument you're passing to ReadPipeAsyncTO.)
Second, I'd avoid ARC with sensitive code, just as a precaution.
Third, from what I see, last argument of ReadPipeAsyncTO is called refcon. Is it a coincidence that callback's first argument is called refCon? Note you're trying to get a text field from messageArg, not refCon.
To extend on my third point…
ReadPipeAsyncTO has an argument called refcon. This is the last argument.
Please pass _printerOutput there. Not a pointer to _printerOutput (do not pass &(_printerOutput)) -- _printerOutput is already a pointer.
Now finally. Look at the first argument of the callback. It's called refcon. In fact -- let's see what Apple docs say about this callback:
refcon
The refcon passed into the original I/O request
My conclusion is that your code should read:
void USBDeviceReadCompletionCallback(void *refCon, IOReturn result, void *messageArg)
{
NSTextField *printerOutput = (__bridge NSTextField *) refCon; // <=== the change is here
NSLog(#"_printerOutput pointer = %p", printerOutput);
}
Can you, please, try this out? I get a feeling that you didn't try this.
Small but possibly important digression: Were it some other object, and if you didn't use ARC, I'd suggest retaining the _printerOutput variable when passing it into ReadPipeAsyncTO, and releasing it in the callback.
But, since the text field should, presumably, have the lifetime of the application, there is probably no need to do so.
ARC probably loses track of the need for the object behind the pointer to exist once it's passed into C code, but it doesn't matter, since the pointer is still stored in the printerOutput property. Besides, once a pointer is in C code, nothing can just "follow it around" and "reset it".
Confusion when it comes to understanding and explaining the concepts is precisely why I said "avoid ARC with sensitive code". :-)

NSMutableDictionary with weak-references: warning when using CFRetain as a callback

I'm trying to create a mutable dictionary that has weak-references for the value objects (the keys behave normally).
This is how i'm trying to do it:
+ (id)mutableDictionaryUsingWeakReferencesWithCapacity:(NSUInteger)capacity
{
CFDictionaryKeyCallBacks keyCallbacks = {0, CFRetain, CFRelease, CFCopyDescription, CFEqual, CFHash};
CFDictionaryValueCallBacks valueCallbacks = {0, NULL, NULL, CFCopyDescription, CFEqual};
id<NSObject> obj = (id)(CFDictionaryCreateMutable(NULL, capacity, &keyCallbacks, &valueCallbacks));
return [obj autorelease];
}
Unfortunately I get a warning (Initialization from incompatible pointer type)in when declaring the keyCallbacks, and i've tracked it down to using CFRetain and CFRelease. For some reason these callbacks do not match the required prototypes (CFDictionaryRetainCallback and CFDictionaryReleaseCallback)
In the documentation it says that an example CFDictionaryRetainCallback should look something like this:
const void *MyCallBack (
CFAllocatorRef allocator,
const void *value
);
But the existing CFRetain is declared as
CFTypeRef CFRetain(CFTypeRef cf);
It's missing the allocator parameter and that's why I think the compiler gives a warning: it's not a perfect match in the signature of the function.
Has anybody tried to do something like this?
Don’t Do That. Use NSMapTable.
if you just want the default CFRetain/CFRelease behaviour, this should work:
void MONDictionaryReleaseCallback(CFAllocatorRef allocator, const void* value) {
#pragma unused(allocator)
assert(value);
if (0 != value) {
CFRelease(value);
}
}
the retain callback should be easy to implement from there.
I managed to get it working using the kCFTypeDictionaryKeyCallBacks constant instead of manually declaring the key callbacks.
The code now looks like this:
id<NSObject> obj = (id)(CFDictionaryCreateMutable(NULL, capacity, &kCFTypeDictionaryKeyCallBacks, &valueCallbacks));
However, i'm still curious why isn't my initial code working
If you don't mind playing with the runtime a bit, this is something I'm working on for a project of mine (it works ATM but it's a bit sloppy). It dynamically creates a new subclass of any object you add and set that object's class to the subclass. The subclass keeps an array of objects that should be notified whenever the object is deallocated. The dictionary adds itself to this array so that it can remove the object if it's ever deallocated.

Resources