I'm facing a problem using VC++ and Debug CRT with a DLL in development.
I have a struct like that, holding some references.
struct DATA
{
TA*& a;
TB*& b;
TC*& c;
TD*& d;
char** chars;
int num_chars;
private:
// because:
// DATA a;
// DATA b;
// a = b; // is impossible
DATA& operator=(const DATA&); // append " = delete;" for C++11
// Default ctor (private because struct should be manually constructed using malloc)
DATA(TA*& a, TB*& b, TC*& c, TD*& d)
: a(a),
b(b),
c(c),
d(d),
chars(NULL),
num_chars(0)
{}
};
and construct it like that:
DATA*& Get()
{
static struct DATA *data = (struct DATA*)malloc(sizeof(struct DATA));
return data;
}
now it should hold uninitialized ref-to-ptrs, which I want to init by:
void func(TA* a, TB* b, TC* c, TD* d)
{
Get()->a = a;
Get()->b = b;
Get()->c = c;
Get()->d = d;
...
}
which works for everything, but ref-to-ptrs..
I'm getting a INVALID_POINTER_WRITE_FILL_PATTERN_cdcdcdcd on the first Get()->a = a; when I do !analyze -v -f using WinDbg (in a remote Kernel Debugging "kd" instance)
Thanks for your help! :)
Edit: Solution
Solution is to use the points from the correct answer.
Making the c'tor public is necessary:
struct DATA
{
TA*& a;
TB*& b;
TC*& c;
TD*& d;
char** chars;
int num_chars;
// Default ctor
DATA(TA*& a, TB*& b, TC*& c, TD*& d)
: a(a),
b(b),
c(c),
d(d),
chars(NULL),
num_chars(0)
{}
private:
// because:
// DATA a;
// DATA b;
// a = b; // is impossible
DATA& operator=(const DATA&); // append " = delete;" for C++11
};
then using placement newto construct the struct:
DATA*& Get(...)
{
// ... some stuff, overloading, other init-method etc. to init and construct like:
static struct DATA *data =
new(malloc(sizeof(struct DATA))) DATA(...); // At least assign ALL references in the c'tor
return data;
}
then use it and maybe assign everything that's no reference:
void func(TA* a, TB* b, TC* c, TD* d)
{
Get(a, b, c, d);
Get()->chars = ...
...
}
free'ing the whole thing needs to be done explicitly by calling the d'tor and free , because we use placement new:
data->~DATA();
free(data);
You cannot declare references without initializing them. Your struct has no default constructor, since you explicitly declare a non-default constructor. Just allocating malloc is not sufficient to create a valid DATA object, as it is a non-POD type.
Just go ahead and try declaring a real default constructor (i.e., DATA() {}), and you'll see that this won't work because of the reference members. If you want to use malloc to allocate non-POD objects, you'll have to use a placement new.
Note that malloc() returns uninitialized memory. C++ objects need to be constructed. The way to get an object into uninitialized memory is to use placement new (this code also adds clean-up):
#include <new>
DATA*& Get()
{
static DATA *data = new(malloc(sizeof(struct DATA))) DATA(...);
static std::unique_ptr<DATA, void(*)(DATA*)> clean(data,
[](DATA* d){
d->~DATA();
free(data);
});
return data;
}
There is no way in C++ to reseat references, i.e., they need to be set during construction. Personally, I wouldn't use malloc() but rather a suitable allocation anyway:
static DATA* data(new DATA(...));
... or, as Jarod42 pointed out, actually
static DATA data(...);
return &data;
Related
I overloaded the operator+ for a self written class further I deal with instances of these class via smart pointers. Now I am wondering if there isn't a better way to make use of the operator. Further I do not get how to pack them back into a shared_ptr.
class A
{
A operator + (A const & other)
{ //do some addition stuff and return new A}
};
std::shared_ptr<A> a, b;
//Currently I add them up like this
auto c = *a.get() + *b.get()
The dereference operator is overloaded for the "smart pointers".
You should add them up like this:
*a + *b
If you want a shared object with the result, you make a shared object from it:
auto c = std::make_shared<A>(*a + *b);
If you had raw pointers you would do this:
auto c = new A(*a + *b);
The similarity is not a coincidence.
On a side note, unless you really intend to share an object among multiple owners, you should not be using shared_ptr at all.
Is there a better way to add two smart pointers?
You cannot add smart pointers. What you're doing here is indirecting through smart pointers and adding the pointed objects.
The call to get() is redundant. You can indirect through the smart pointer directly: *a + *b.
Further I do not get how to pack them back into a shared_ptr
A simple way to create a shared pointer is std::make_shared.
You can implement an operator for a shared_ptr specialization:
class A
{
...
};
std::shared_ptr<A> operator+(const std::shared_ptr<A>& a1, const std::shared_ptr<A>& a2)
{
return std::make_shared<A>(*a1 + *a2);
}
and simple use
std::shared_ptr<A> a1, a2;
std::shared_ptr<A> a3 = a1 + a2;
A full example could be
class Value
{
private:
int value;
public:
Value(int value_): value(value_)
{}
Value operator+(Value other) const
{
return Value(value + other.value);
}
};
std::shared_ptr<Value> operator+(const std::shared_ptr<Value>& a, const std::shared_ptr<Value>& b)
{
return std::make_shared<Value>(*a + *b);
}
So you could use
Value a, b;
Value c = a + b;
and also
std::shared_ptr<Value> pa, pb;
std::shared_ptr<Value> pc = pa + pb;
I want to have class scope alias to the vector from an argument.
For exapmale:
class Solution {
private:
vector<int> b; // I want that &b = a, where a from function solve
int f(int i) {
// here I want to use vector<int> a,
// not passing it as a function argument every time
}
public:
int solve(vector<int>& a) {
// here I want to do smth like b = a; which works for O(1)
}
};
Unfortunatelly, I can't just declare vector<int> &b; , because of the error:
declaration of reference variable 'b' requires an initializer
Could you please, explain how to do it in C++11/14?
Update: I can't change the declaration of int solve(vector<int>& a), the interface provided from outside.
Update: I've changed the code to the more explicit. Looks like I shouldn't do again because in answers and comments people use original variable names. I'm sorry, don't have much experience with StackOverflow.
Maybe this?
class Solution {
public:
vector<int> a;
int maxCoins(const vector<int>& _a) { // const because copying
a.assign( _a.begin(), _a.end() );
}
};
But know that you can also do this if you want a reference to the original vector<int> rather than a copy:
class Solution {
public:
vector<int> & a;
int maxCoins(vector<int>& _a) : a( _a ) {}
};
Update
This is probably closest. You cannot re-initialize a reference, but then this is exactly the use-case for pointers.
class Solution {
public:
vector<int> * a;
int f(int i) {
a->size(); // can access indirectly
(*a)[1]; // element access is slightly trickier
vector<int> & _a = *a; // or can create a direct ref
_a.size();
}
int solve(vector<int>& _a) {
a = &_a; // store address to _a. a reference is like any local variable unless doing something funny
}
};
Update 2 - using no pointers
#include <functional>
class Solution {
public:
// vector<int> a;
typedef vector<int> datatype;
datatype blankref;
std::reference_wrapper<datatype> a = blankref;
int f(int i) {
vector<int> & _a = a;
}
int solve(vector<int>& _a) {
a = std::ref(_a);
}
};
You can't avoid the fact that references are assign-once. References in a class instance have to be assigned using initializer syntax. To have a re-usable reference, you need to have a newly initialized object each time.
To help us here, thanks to advice in comments, there is std::reference_wrapper<T> type that can hold instances of references. It can be assigned to using std::ref( _a ) repeatedly.
Honestly pointers are not inelegant when used right, imo. It comes down to use case and what you believe you would need. Performance wise this probably won't be as good as with pointers (because of temporary objects being constructed), though no guarantees... it should perform similarly in any case.
I have a question regarding initialization of a new structure in c++. I am new to c++.
typedef struct
{
int n;
char anArray*;
} myStruct;
void newStruct ( myStruct **ms, int x)
{
myStruct* local_ms = new myStruct;
local_ms->n = x;
local_ms->anArray= new char[sizeof(char)*n];
ms = &local_ms;
}
When I call newStruct with an void pointer, my intention is for it to allocate the memory in myStruct and then store the pointer to the new structure in ms, for my use later. Unfortunately, I think local_ms is only local in scope and is thus lost upon return from newStruct.
That being said, I'm not sure how to appropriately initialize myStruct! Thoughts?
"I think local_ms is only local in scope and is thus lost upon return
from newStruct."
Change:
ms = &local_ms;
to:
*ms = local_ms;
would help avoid the problem, which assigns the pointer of the newStruct object to the *ms.
ms = &local_ms;
This modifies the local pointer ms to point to the other local pointer to the allocated structure. However, what you want is to modify the caller's pointer. ms is a pointer to that, so you want to modify the thing that ms points to:
*ms = local_ms;
But this isn't C, so you could use simpler reference semantics:
void newStruct ( myStruct *& ms, int x)
// ^^ reference to pointer
{
// ...
ms = local_ms;
}
// usage
myStruct * ms;
newStruct(ms, 42);
But the language (C or C++) gives a cleaner way to return a value from a function: you can return a value from the function.
myStruct * newStruct(int x)
{
// ...
return local_ms;
}
// usage
myStruct * ms = newStruct(42);
But in C++, we can use constructors, rather than arbitrary functions, to initialise new objects:
struct myStruct { // no need for that typedef nonsense
explicit myStruct(int n) :
n(n),
anArray(new char[n]) // sizeof(char) is 1 by definition
{}
int n;
char *anArray; // * goes before the variable name
};
// usage
myStruct ms(42); // don't use `new` unless you really need it
Now just one thing is missing: anArray is never deleted, giving a memory leak. The simplest fix is to use a dynamic array type from the standard library: either string or vector.
struct myStruct {
explicit myStruct(int n) : n(n), anArray(n) {}
int n;
std::string anArray;
};
But of course, n is now redundant; you should get rid of it and use anArray.size() instead. This means that the structure itself is pretty pointless; you just need
std::string ms(42);
#include <memory>
#include <iostream>
// [A] Starting with:
typedef struct
{
int n;
// Not char anArray*;
char* anArray;
} myStruct;
void newStruct ( myStruct **ms, int x)
{
myStruct* local_ms = new myStruct;
local_ms->n = x;
// Fix: use x
local_ms->anArray = new char[sizeof(char)*x];
ms = &local_ms;
}
// [B] Avoid myStruct **ms, use std::size_t
// and get rid of sizeof(char) (which is one, always)
myStruct* newStruct (std::size_t x)
{
myStruct* ms = new myStruct;
ms->n = x;
ms->anArray= new char[x];
return ms;
}
// [C] Manage memory in a class (pair new/delete).
// Btw. typedef struct is C (not C++)
class myStruct2
{
public:
myStruct2(std::size_t n)
: n(n), anArray(new char[n])
{}
~myStruct2() {
delete [] anArray;
}
std::size_t size() const { return n; }
const char* array() const { return anArray; }
char* array() { return anArray; }
private:
// If you do not define these, avoid copies (C++11 has '= delete'):
myStruct2(const myStruct2&);
myStruct2& operator = (const myStruct2&);
std::size_t n;
char* anArray;
};
// Still having a new without delete in the same (logically) scope - which is bad:
myStruct2* newStruct2 (std::size_t n)
{
return new myStruct2(n);
}
// [D] Manage memory with a shared pointer.
// Still having an new without a delete in the same (logically) scope,
// but now the memory is managed by the shared pointer - that is good!
// (If there is no std::shared_ptr: boost::shared_ptr)
std::shared_ptr<myStruct2> make_shared_struct2(std::size_t n)
{
return std::shared_ptr<myStruct2>(new myStruct2(n));
}
// [E] Avoid the pointer to myStruct2
// If you have defined the copy constructor and assignment operator:
// myStruct2 make_struct2(std::size_t n)
// {
// return myStruct2(n);
// }
// [F] But actually it is trivial
typedef std::vector<char> myStruct3;
myStruct3 make_struct3(std::size_t n)
{
return myStruct3(n);
}
I have been struggling with that issue long time. It seems to be quite ineffective in C++ that array of class B created in class A have to be initialized by default constructor. Is there any way to avoid that behavior ? I implement a register of people. If I create it with count references, I get a lot of default constructor callings and it seems to be less effective that it should be. Also I have to create default constructor which is unnecessary.
When you are creating an array of objects, be it a static array (Person people[1000]) or dynamically allocated (Person* people = new Person[1000]), all 1000 objects will be created and initialized with the default constructor.
If you want to create space for the objects, but not create them just yet, you can either use a container like std::vector (which implements a dynamically sized array), or use an array of pointers, like Person* people[1000] or Person** people = new Person*[1000] - in this case, you can initialize all items with NULL to indicate empty records, and then allocate objects one by one: people[i] = new Person(/* constructor arguments here */), but you will also have to remember to delete each object individually.
I think I have the solution you are aiming for. I tested this on GCC 4.6 and it may require modification for MSVC++ for the alignment bit, but here is the sample output and the source code:
Source Code (tested with GCC 4.6):
#include <cstdio>
#include <cstring>
#include <new>
// std::alignment_of
template <typename T, std::size_t capacity>
class StaticVector
{
public:
StaticVector() : _size(0)
{
// at this point we've avoided actually initializing
// the unused capacity of the "static vector"
}
~StaticVector()
{
// deconstruct in reverse order of their addition
while (!empty())
pop_back();
}
void push_back(const T &src)
{
// at this point we initialize the unused array entry by copy
// constructing it off the passed value
new (data() + _size) T(src);
_size++;
}
void pop_back()
{
_size--;
// we manually call the deconstructor of the entry we are marking as unused
data()[_size].~T();
}
bool empty() const {return _size == 0;}
std::size_t size() const {return _size;}
// NOTE: you'd better index only into constructed data! just like an std::vector
T & operator[](int i) {return *data()[i];}
const T & operator[](int i) const {return *data()[i];}
T * data() {return reinterpret_cast<T*>(_data);}
const T * data() const {return reinterpret_cast<const T*>(_data);}
protected:
// NOTE: I only tested this on GCC 4.6, it will require some
// conditional compilation to work with MSVC and C++11
#if 1 // for GCC without c++11
char _data[sizeof(T[capacity])] __attribute__((aligned(__alignof__(T))));
#else // UNTESTED: The C++11 way of doing it?
alignas(T) char _data[sizeof(T[capacity])]; // create a suitable sized/aligned spot for the array
#endif
std::size_t _size;
};
// NOTE: lacks a default constructor, only
// constuctor that takes parameters
class B
{
public:
B(int param1, const char param2[])
{
printf("Constructing B at %08X with parameters (%i, %s)\n", (int)this, param1, param2);
x = param1;
strcpy(buffer, param2);
}
~B()
{
printf("Deconstructing B at %08X\n", (int)this);
}
// NOTE: only provided to do the printf's, the default
// copy constructor works just fine
B(const B &src)
{
printf("Copying B from %08X to %08X\n", (int)(&src), (int)this);
x = src.x;
memcpy(buffer, src.buffer, sizeof(buffer));
}
protected:
int x;
char buffer[128];
};
class A
{
public:
StaticVector<B, 8> staticVectorOfB;
};
int main()
{
printf("PROGRAM START\n");
A a;
a.staticVectorOfB.push_back(B(0, "Uno"));
a.staticVectorOfB.push_back(B(1, "Dos"));
a.staticVectorOfB.push_back(B(2, "Tres"));
printf("PROGRAM END\n");
return 0;
}
Sample Output:
PROGRAM START
Constructing B at 0022FDC4 with parameters (0, Uno)
Copying B from 0022FDC4 to 0022F9A0
Deconstructing B at 0022FDC4
Constructing B at 0022FE48 with parameters (1, Dos)
Copying B from 0022FE48 to 0022FA24
Deconstructing B at 0022FE48
Constructing B at 0022FECC with parameters (2, Tres)
Copying B from 0022FECC to 0022FAA8
Deconstructing B at 0022FECC
PROGRAM END
Deconstructing B at 0022FAA8
Deconstructing B at 0022FA24
Deconstructing B at 0022F9A0
First, you do not need to create default constructor, because otherwise the compiler will generate its code. I do not think there is a clean way to avoid calling default constructor on the object (perhaps optimizer would strip it out for the array), but there is surely a dirty one:
class B
{
};
class A
{
private:
char _array[sizeof(B)*5];
B* getB() {return (B*)_array;}
};
Then you can still use the pointer the same way as you would use fixed size array. sizeof and increment/decrement will not function though.
I guess you should not be bothered too much by "inefficiences" from default constructor. They are there for a reason. Otherwise, if default constructor really has no job to do, it should be inlined and then it will generate no overhead to execution.
How is the array, is class B inside A? Is it like B arr[size];? Instead use vector so that you can init the size in initialization and then push objects. Or dynamic array with new like below. The initfunc can create you register. Since the initfunc is called in initialization of the constructor it will be efficient.
class B
{
};
class A
{
B *barray;
B* initfunc()
{
B* tmp = new B[5];
//init elements of B
return tmp;
}
public:
A():barray(initfunc())
{
}
~A()
{
delete[] barray;
}
};
//the code is not exception safe, vector recommended.
Is there a standard container for a sequence of fixed length, where that length is determined at runtime. Preferrably, I'd like to pass an argument to the constructor of each sequence element, and use that argument to initialize a const member (or a reference). I'd also like to obtain the sequence element at a given index in O(1). It seems to me that all of my requirements cannot be met at the same time.
I know std::array has fixed length, but that length has to be known at compile-time.
std::vector has dynamic size, and allows passing contructor arguments using emplace. Although you can reserve memory to avoid actual reallocations, the type still has to be movable to theoretically allow such reallocations, which e.g. prevents const members.
Then there is std::list and std::forward_list, which don't require a movable type, but which are still resizable and will perform rather poorly under random-access patterns. I also feel that there might be considerable overhead associated with such lists, since each list node will likely be allocated separately.
Strangely enough, std::valarray is my best bet so far, since it has a fixed length and won't resize automatically. Although there is a resize method, your type won't have to be movable unless you actually call that method. The main deficit here is the lack for custom constructor arguments, so initializing const members isn't possible with this approach.
Is there some alternative I missed? Is there some way to adjust one of the standard containers in such a way that it satisfies all of my requirements?
Edit: To give you a more precise idea of what I'm trying to do, see this example:
class A {
void foo(unsigned n);
};
class B {
private:
A* const a;
const unsigned i;
public:
B(A* aa) : a(aa), i(0) { }
B(A* aa, unsigned ii) : a(aa), i(ii) { }
B(const std::pair<A*, unsigned>& args) : B(args.first, args.second) { }
B(const B&) = delete;
B(B&&) = delete;
B& operator=(const B&) = delete;
B& operator=(B&&) = delete;
};
void A::foo(unsigned n) {
// Solution using forward_list should be guaranteed to work
std::forward_list<B> bs_list;
for (unsigned i = n; i != 0; --i)
bs_list.emplace_front(std::make_pair(this, i - 1));
// Solution by Arne Mertz with single ctor argumen
const std::vector<A*> ctor_args1(n, this);
const std::vector<B> bs_vector(ctor_args1.begin(), ctor_args1.end());
// Solution by Arne Mertz using intermediate creator objects
std::vector<std::pair<A*, unsigned>> ctor_args2;
ctor_args2.reserve(n);
for (unsigned i = 0; i != n; ++i)
ctor_args2.push_back(std::make_pair(this, i));
const std::vector<B> bs_vector2(ctor_args2.begin(), ctor_args2.end());
}
Theoretically vector has the properties you need. As you noted, actions that possibly do assignments to the contained type, including especially any sequence modifications (empace_back, push_back, insert etc.) are not supported if the elements are noncopyable and/or nonassignable. So to create a vector of noncopyable elements, you'd have to construct each element during vector construction.
As Steve Jessop points out in his answer, if you define the vector const in the first place you won't even be able to call such modifying actions - and of course the elements remain unchanged as well.
If I understand correctly, you have only a sequence of constructor arguments, not the real object sequence. If it's only one argument and the contained type has a corresponding constructor, things shoule be easy:
struct C
{
const int i_;
C(int i) : i_(i) {}
};
int main()
{
const std::vector<C> theVector { 1, 2, 3, 42 };
}
If the constructor is explicit, you have to make a list first or explicitly construct the objects in the initializer-list:
int main()
{
auto list = { 1, 2, 3, 4 };
const std::vector<C> theVector (std::begin(list), std::end(list));
const std::vector<C> anotherVector { C(1), C(44) };
}
If it's more than just one argument per constructed object, consider a intermediate creator object:
struct C
{
const int i_;
C(int i, int y) : i_(i+y) {}
};
struct CCreator
{
int i; int y;
explicit operator C() { return C(i,y); }
};
int main()
{
const std::vector<CCreator> ctorArgs = { {1,2}, {3,42} };
const std::vector<C> theVector { begin(ctorArgs), end(ctorArgs) };
}
I think const std::vector<T> has the properties you ask for. Its elements aren't actually defined with const, but it provides a const view of them. You can't change the size. You can't call any of the member functions that need T to be movable, so for normal use they won't be instantiated (they would be if you did an extern class declaration, so you can't do that).
If I'm wrong, and you do have trouble because T isn't movable, try a const std::deque<T> instead.
The difficulty is constructing the blighter -- in C++11 you can do this with an initializer list, or in C++03 you can construct a const vector from a non-const vector or from anything else you can get iterators for. This doesn't necessarily mean T needs to be copyable, but there does need to be a type from which it can be constructed (perhaps one you invent for the purpose) .
Add a level of indirection by using a std::shared_ptr. The shared pointer can be copied and assigned as usual, but without modifying the object that is pointed to. This way you should not have any problems, as the following example shows:
class a
{
public:
a(int b) : b(b) { }
// delete assignment operator
a& operator=(a const&) = delete;
private:
// const member
const int b;
};
// main
std::vector<std::shared_ptr<a>> container;
container.reserve(10);
container.push_back(std::make_shared<a>(0));
container.push_back(std::make_shared<a>(1));
container.push_back(std::make_shared<a>(2));
container.push_back(std::make_shared<a>(3));
Another advantage is the function std::make_shared which allows you to create your objects with an arbitrary number of arguments.
Edit:
As remarked by MvG, one can also use std::unique_ptr. Using boost::indirect_iterator the indirection can be removed by copying the elements into a new vector:
void A::foo(unsigned n)
{
std::vector<std::unique_ptr<B>> bs_vector;
bs_vector.reserve(n);
for (unsigned i = 0; i != n; ++i)
{
bs_vector.push_back(std::unique_ptr<B>(new B(this, i)));
}
typedef boost::indirect_iterator<std::vector<std::unique_ptr<B>>::iterator> it;
// needs copy ctor for B
const std::vector<B> bs_vector2(it(bs_vector.begin()), it(bs_vector.end()));
// work with bs_vector2
}
I also encounter this problem, the use case in my code is to provide a thread-safe vector, the elements number is fixed and are atomic numbers. I have read all the great answers here. I think we may also consider my solution:
Just inherited the std::vector and hide the modifiers such as push_back, emplace_back, erase, then we get a fixed size vector. We can only access and modify the elements with operator [].
template <typename T>
class FixedVector : protected std::vector<T> {
public:
using BaseType = std::vector<T>;
FixedVector(size_t n) : BaseType(n) {}
FixedVector(const T &val, size_t n) : BaseType(val, n) {}
typename BaseType::reference operator[](size_t n) {
return BaseType::operator[](n);
}
};