class K {
public:
K(int a, int n) : n(n) {
}
static void allocate(unsigned number, unsigned n) {
K* w = reinterpret_cast<K*> (::operator new( sizeof (K) * number));
for (int i = 0; i < number; i++) {
new( (void*) (w + i))K(24, n);
//(w)->K::K(24,n);
}
}
private:
const int n;
};
Why the first way ( new( (void*) (w + i))K(24, n);) don't make error and the second way ((w)->K::K(24,n);) make error? Eventually, how repair it?
Tha allocate is static, so why I have access to n which is private?
I'm going to state my understanding of what you're trying to do, which is not 100% clear to the respondents. Since you don't have a default constructor for your class, you cannot allocate them in an array using new[]. Your recourse is to invoke the constructors manually using placement new.
In general, try to make a default constructor for classes that need to be allocated with new[]. Then you can just go update them after you've allocated them. This is simpler and easier to read. For example, w = new K[number]; and delete[] w; handles everything for you, but it can only call the default constructor. So you must do "post construction initialization" with your own function to set them up the way you want.
If you really want to call the individual constructors using placement new, you can and it is safe. It's not my recommended design, but neither is it as evil as some might assume. Your code works, but you don't do anything with w after you're done, so it's a leak... but examining it in the debugger, it has called the constructor on each one, just like you wanted. You should note that you are reusing n in different scopes, which is confusing. You should disambiguate that. The n from allocate is being fed into each constructor.
One other important note though, and this is the disadvantage of the design of using placement new here. You must:
Manually invoke the destructor on each element when you are done. Therefore, you must track the length of the array manually until freeing.
Free w the matching way it was allocated. Do not use delete[] if you didn't use new[].
static members may access the private data of any instance of its type. Dem's da rules.
However, here, you're using the function argument.
I'm not even going to comment on your mental memory allocations.
Related
As an academic exercise I created a custom vector implementation I'd like to support copying of non-pod types.
I would like the container to support storing elements that do not provide a default constructor.
When I reserve memory for the vector, and then push_back an element (which manages it's own resources and has a copy and assignment operator implemented - I'm ignoring move constructors for the moment) I have an issue using the copy-swap idiom for that type.
Because the swap happens on a type that is still uninitialised memory, after the swap, the destructor which is called for the temporary will attempt to free some piece of uninitialised data which of course blows up.
There are a few possible solutions I can see. One is ensure all non-pod types implement a default constructor and call that (placement new) on each element in the collection. I'm not a fan of this idea as it seems both wasteful and cumbersome.
Another is to memset the memory for the space of the type in the container to 0 before doing the swap (that way the temporary will be null and calling the destructor will operate without error). This feels kind of hacky to me though and I'm not sure if there is a better alternative (see the code below for an example of this) You could also memset all the reserved space to 0 after calling reserve for a bunch of elements but again this could be wasteful.
Is there documentation on how this is implemented for std::vector as calling reserve will not call the constructor for allocated elements, whereas resize will (and for types not implementing a default constructor a constructed temporary can be passed as a second parameter to the call)
Below is some code you can run to demonstrate the problem, I've omitted the actual vector code but the principle remains the same.
#include <iostream>
#include <cstring>
// Dumb example type - not something to ever use
class CustomType {
public:
CustomType(const char* info) {
size_t len = strlen(info) + 1;
info_ = new char[len];
for (int i = 0; i < len; ++i) {
info_[i] = info[i];
}
}
CustomType(const CustomType& customType) {
size_t len = strlen(customType.info_) + 1;
info_ = new char[len];
for (int i = 0; i < len; ++i) {
info_[i] = customType.info_[i];
}
}
CustomType& operator=(CustomType customType) {
swap(*this, customType);
return *this;
}
void swap(CustomType& lhs, CustomType& rhs) {
std::swap(lhs.info_, rhs.info_);
}
~CustomType() {
delete[] info_;
}
char* info_;
};
int main() {
CustomType customTypeToCopy("Test");
// Mimics one element in the array - uninitialised memory
char* mem = (char*)malloc(sizeof(CustomType));
// Cast to correct type (would be T for array element)
CustomType* customType = (CustomType*)mem;
// If memory is cleared, delete[] of null has no effect - all good
memset(mem, 0, sizeof(CustomType));
// If the above line is commented out, you get malloc error - pointer
// being freed, was not allocated
// Invokes assignment operator and copy/swap idiom
*customType = customTypeToCopy;
printf("%s\n", customType->info_);
printf("%s\n", customTypeToCopy.info_);
return 0;
}
Any information/advice would be greatly appreciated!
Solved!
Thank you to #Brian and #Nim for helping me understand the use case for when assignment (copy/swap) is valid.
To achieve what I wanted I simply needed to replace the line
*customType = customTypeToCopy;
with
new (customType) CustomType(customTypeToCopy);
Invoking the copy constructor not the assignment operator!
Thanks!
You don't use copy-and-swap for construction.
You use copy-and-swap for assignment in order to solve the following problem: the left side of the assignment is an already-initialized object, so it needs to free the resources it holds before having the right side's state copied or moved into it; but if the copy or move construction fails by throwing an exception, we want to keep the original state.
If you're doing construction rather than assignment---because the target is uninitialized---the problem solved by copy-and-swap doesn't exist. You just invoke the constructor with placement new. If it succeeds, great. If it fails by throwing an exception, the language guarantees that any subobjects already constructed are destroyed, and you just let the exception propagate upward; in the failure case the state of the target will be the same as it was before: uninitialized.
Since C++11, when using the move assignment operator, should I std::swap all my data, including POD types? I guess it doesn't make a difference for the example below, but I'd like to know what the generally accepted best practice is.
Example code:
class a
{
double* m_d;
unsigned int n;
public:
/// Another question: Should this be a const reference return?
const a& operator=(a&& other)
{
std::swap(m_d, other.m_d); /// correct
std::swap(n, other.n); /// correct ?
/// or
// n = other.n;
// other.n = 0;
}
}
You might like to consider a constructor of the form: - ie: there are always "meaningful" or defined values stores in n or m_d.
a() : m_d(nullptr), n(0)
{
}
I think this should be rewriten this way.
class a
{
public:
a& operator=(a&& other)
{
delete this->m_d; // avoid leaking
this->m_d = other.m_d;
other.m_d = nullptr;
this->n = other.n;
other.n = 0; // n may represents array size
return *this;
}
private:
double* m_d;
unsigned int n;
};
should I std::swap all my data
Not generally. Move semantics are there to make things faster, and swapping data that's stored directly in the objects will normally be slower than copying it, and possibly assigning some value to some of the moved-from data members.
For your specific scenario...
class a
{
double* m_d;
unsigned int n;
...it's not enough to consider just the data members to know what makes sense. For example, if you use your postulated combination of swap for non-POD members and assignment otherwise...
std::swap(m_d, other.m_d);
n = other.n;
other.n = 0;
...in the move constructor or assignment operator, then it might still leave your program state invalid if say the destructor skipped deleting m_d when n was 0, or if it checked n == 0 before overwriting m_d with a pointer to newly allocated memory, old memory may be leaked. You have to decide on the class invariants: the valid relationships of m_d and n, to make sure your move constructor and/or assignment operator leave the state valid for future operations. (Most often, the moved-from object's destructor may be the only thing left to run, but it's valid for a program to reuse the moved-from object - e.g. assigning it a new value and working on it in the next iteration of a loop....)
Separately, if your invariants allow a non-nullptr m_d while n == 0, then swapping m_ds is appealing as it gives the moved-from object ongoing control of any buffer the moved-to object may have had: that may save time allocating a buffer later; counter-balancing that pro, if the buffer's not needed later you've kept it allocated longer than necessary, and if it's not big enough you'll end up deleting and newing a larger buffer, but at least you're being lazy about it which tends to help performance (but profile if you have to care).
No, if efficiency is any concern, don't swap PODs. There is just no benefit compared to normal assignment, it just results in unnecessary copies. Also consider if setting the moved from POD to 0 is even required at all.
I wouldn't even swap the pointer. If this is an owning relationship, use unique_ptr and move from it, otherwise treat it just like a POD (copy it and set it to nullptr afterwards or whatever your program logic requires).
If you don't have to set your PODs to zero and you use smart pointers, you don't even have to implement your move operator at all.
Concerning the second part of your question:
As Mateusz already stated, the assignment operator should always return a normal (non-const) reference.
Edit: I originally posed this question out of context so I've reworked it. I've left as much as possible unchanged so most of your responses will still apply.
I'm having trouble understanding how to implement a constructor which accepts a pointer to an array of pointers.
I have the following class which contains a member, bodies, of type Body** (i.e. it is a pointer to an array of pointers to body objects).
class Galaxy
{
private:
int n; // Number of bodies in galaxy.
Body** bodies; // Ptr to arr of ptrs to Body objects.
public:
Galaxy();
Galaxy(int, Body**);
// Some other member functions.
};
Here is the implementation of the constructors:
// Default constructor. Initializes bodies to null pointer.
Galaxy::Galaxy() : bodies(NULL) {}
// Alternate constructor. Here I try to perform a deep copy of bodiesIn.
Galaxy::Galaxy(int nIn, Body** bodiesIn)
{
n = nIn;
// Allocate memory for an array of n pointers to Body objects.
bodies = new Body*[n];
// Perform deep copy.
for (int i=0; i<n; i++)
{
bodies[i] = new Body;
*bodies[i] = *bodiesIn[i];
}
}
Is this method sound, or is there a preferred way to construct such an object.
P.S. I realize it would be easier to code this with std::vector's, however the size of the array doesn't change, and minimizing memory usage is important.
There's lots wrong with your function:
Creating an object and then immediately assigning to it is inefficient, use the copy ctor instead.
If an exception is thrown by any new-expression but the first one or by one of the assignments, you are leaking objects.
Better take a std::size_t for the size, it's designed for it.
Better swap the arguments, that's more idiomatic.
You don't return the copy at the moment
Why not templatize it?
BTW: std::unique_ptr does not add any overhead, but provides plenty of comfort and safety.
Inside a method can one create an uninitialised object from the class?
Here's some context: imagine a class where the constructors all allocate memory:
class NumberArray
{
size_t m_Size;
int *m_Numbers;
public:
NumberArray() { m_Size = 1; m_Numbers = new int[1]; m_Numbers[0] = 0; }
// . . . other methods for manipulating or constructing . . .
~NumberArray() { delete[] m_Numbers; }
// What if I had a method that concatenates two arrays?
NumberArray ConcatenateWith(const NumberArray &) const;
};
Inside such a method one would desire to create an uninitialised object of class NumberArray, and then 'construct' a new object based on this and the object in the parameter? AKA:
NumberArray NumberArray::ConcatenateWith(const NumberArray &other) const
{
// Mystery manner of creating an uninitialised NumberArray 'returnObject'.
returnObject.m_Size = m_Size + other.m_Size;
returnObject.m_Numbers = new int[returnObject.m_Size];
std::copy(m_Numbers, m_Numbers + m_Size, returnObject.m_Numbers);
std::copy(other.m_Numbers, other.m_Numbers + other.m_Size, returnObject.m_Numbers + m_Size);
return returnObject;
}
What's the best way of doing this? Basically, I don't want the default constructor to create a size 1 array that I will just delete and then allocate a new array for again anyway.
It's not entirely clear what you are trying to do, but if all you want is to create a new instance of the class and not have a constructor other than the default constructor called then do just that.
All you have to do is create a private constructor, that has a different signature from the default constructor and which does not allocate memory (or differs in whatever way you need it to differ from the default constructor); then simply have your class invoke that constructor internally, when necessary.
What you're asking for is placement new. This looks something like this:
#include <cstdlib>
#include <new>
void* mem = std::malloc(sizeof(T)); // memory for a T (properly aligned per malloc)
T* x = new (mem) T; // construct a T in that memory location
x->~T(); // destruct that T
std::free(mem); // and free the memory
Doing this correctly (in an exception-safe manner with properly managed and aligned memory) is not a trivial task. You need to be careful about the lifetime of your objects.
For your question, you are describing exactly what std::vector does. It allocates raw uninitialized memory and constructs inserted elements directly into that memory. And lots of its code is dedicated to just getting the lifetime and memory management correct and exception safe!
You should strongly prefer to use std::vector instead of writing it yourself.
There is no well-defined way, as far as I'm aware, to create an object without invoking it's constructor. This is regardless of whether you have access to its public interface or not, though you could implement a private or protected constructor if you want to restrict who can invoke it. There is otehrwise no restrictions on creating new instances of a class from its own internal methods, in fact it is quite common to define a private constructor and a static public method that create instances of said object if you want to restrict under which conditions said object can be created.
If you want to, you can allocated sufficient memory for an object and reinterpret_cast a pointer to that memory to a pointer of the type you want. This usually works for POD's, but since many implementations (if not all) of polymorphic inheritance in c++ adds a pointer to a vtable to polymorphic instances this approach will usually, if not always, fail for those.
In short, create a private constructor and have a static method invoke it and then do any other work that you need is my recommendation.
I think this may be similar to what you want, an 'anonymous' class of sorts:
struct test {
virtual void doSomething() {
puts("test");
}
};
struct a {
test *t() {
struct b : test {
void doSomething() {
puts("b");
};
};
return new b;
};
};
int main()
{
a a;
a.t()->doSomething(); // outputs 'b'
}
However, due to slicing and how new works on C++, you must return a pointer and the 'anonymous' type must have a name, even if it's restricted only to the function.
If you could edit the OP and clarify exactly what you wish to accomplish by this, maybe we could help you more.
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;