Object creation with varying buffer size - c++

I have a class which allocates array of fixed buffer as below.
class CMyBuffer
{
public:
CMyBuffer() { /* constructor ... */ }
~CMyBuffer() { /* destructor ... */ }
int copy(char *source, int len);
char m_szBuf[MYBUF_SIZE * sizeof(char)];
int m_nLen;
};
When an object of this class is created, there would be memory allocation for the object including the fixed buffer of size MYBUF_SIZE. So as to say there would be one call to malloc() [In good old 'C' thinking].
I was wondering if it is possible to vary the buffer size based on constructor parameter. Of course, it is possible if we make m_szBuf a pointer and allocate memory in the constructor based on the constructor parameter (which specified size). But I think this would end up calling memory allocation twice (once for the object overall and once for the pointer to the buffer within the object). Is there a way to vary the buffer size in the object but with only one call to memory allocation? The concern for exploring this approach is to reduce heap memory fragmentation.

So as to say there would be one call to malloc() [In good old 'C'
thinking].
You are writing c++, not c, right?
In c++ arrays with a size that is only known at runtime are std::vectors. For someone used to get their hands dirty it might be a bit lame, but as a matter of fact you really need very good reasons not to use std::vector. It is rare that std::vector cannot do what you need for a dynamic array.
I was wondering if it is possible to vary the buffer size based on
constructor parameter.
Yes, of course:
class CMyBuffer
{
public:
CMyBuffer(size_t size) : m_szBuf(size) { /* constructor ... */ }
~CMyBuffer() { /* destructor ... */ }
int copy(char *source, int len);
std::vector<char> m_szBuf;
};
You also do not need to keep track of the size of the vector yourself (that is c-thinking ;).
Maybe you think, well std::vector is fine, but it does not help me because I still need a char* in some places of my code. However, std::vector can give you access to the underlying array via std::vector::data().

If you only have a few expected sizes of buffer, and they're known at compile time, you can use templating to generate classes for each size:
template <size_t N>
class CMyBuffer
{
public:
char m_szBuf[N * sizeof(char)];
int m_nLen = N;
};
// usage
CMyBuffer<MYBUF_SIZE> buff;
CMyBuffer<256> buffBig;

Related

Converting c implemented static allocated workspace to c++

I have a working function implementation in c that requires a large locally allocated chunk of memory as a working space. This function gets called a lot in succession where it is guaranteed that the required amount of working space does not change. To optimize the function I have refactored it to allocate a static single continuous piece of memory the first time it is called, that is only released when it is asked to. It looks something like this
void worker(struct* ptr, size_t m) {
static double *stack;
static size_t sz_stack;
static double *alpha;
static double *delta;
if (!ptr) {
if (stack) {
free(stack);
}
stack = NULL;
sz_stack = 0;
return;
}
if (!stack) {
sz_stack = 2*m;
stack = calloc(sz_stack, sizeof(*stack));
if (stack==NULL)
// Error and cleanup
alpha = stack;
delta = alpha + m;
}
// Do work using alpha and delta as arrays
return;
}
The caller can call this function successively where ptr will hold the final result as long as the problem size given by m does not change. When the caller is done with the function, or the problem size changes, he calls worker(NULL, 0); and the allocated memory will be freed.
I am now working on rewriting this codebase to c++ and as the best practices tell me I have used individual std::vector for alpha and delta instead of the contiguous stack. However, profiling revealed that there is a huge bottleneck as the std::vector containers are allocated and free'd each and every function call.
My question now is:
What is the modern c++ way to maintain a contiguous piece of working space for a function in between calls?
If it is guaranteed that the required working space will not be changing during contiguous function calls (as you mentioned), to me it seems the simplest solution would be to use a static array (somewhat similar to your C code, but using 'new' and 'delete[]' instead of 'calloc' and 'free').
The C++ way would be to have a class with a private array that you can then manage.
It seems to me that the way you are handling static memory is very analogous to a constructor and destructor. I would have the array as the sole private member and then your worker function as a public member function.
Also, in terms of performance, STL can do some strange things and each implementation can be more or less strange than the next. If you really want speed (as you've seen), sometimes you have to handle things yourself.
static is a dreadful thing because it plays really badly with thread safety and is wholly unnecessary.
The modern way is one of the following:
Declare the memory further up on the stack. vector<> or array<> or even malloc if you like. Pass a pointer (or, equivalently, reference) to this memory into your function.
int main()
{
vector<double> storage;
while (1)
{
worker(&storage,0,0);
}
return 0;
}
Or, write your function as a member of a class. Declare the memory as a member of your class. Create one instance of your class, then call the function repeatedly:
struct oo_hack
{
void worker (struct* ptr, size_t m)
{
// Do some things using storage
}
vector<double> storage;
}
int main()
{
oo_hack myhack; // This is on the stack, but has a vector inside
while (1)
{
myhack.worker(0,0);
}
return 0;
} // memory gets freed here
I'd suggest declaring the memory further up on the stack and passing it into the functions, but you may prefer the second.

how many elements in dynamically allocated class array

I have a simple class called tire. Now I want to dynamically allocate the number of tires for a vehicle when a vehicle object is created. For this, I want to create an array of tire-class objects with size equal to the number of tires. To check my code, I would like to print the number of objects in the tire-class array.
The question is: Is there a function which can check how many elements are in my tire class array? Can I use the sizeof() function?
Here is the code:
#include <iostream>
// create a class for the tires:
class TireClass {
public:
float * profileDepths;
};
// create class for the vehicle
class vehicle {
public:
int numberOfTires;
TireClass * tires;
int allocateTires();
};
// method to allocate array of tire-objects
int vehicle::allocateTires() {
tires = new TireClass[numberOfTires];
return 0;
};
// main function
int main() {
vehicle audi;
audi.numberOfTires = 4;
audi.allocateTires();
// check if the correct number of tires has been allocated
printf("The car has %d tires.", sizeof(audi.tires));
// free space
delete [] audi.tires;
return 0;
};
No, there's none. Consider using std::vector. Or just store tires count in some other variable (maybe numberOfTires is good enough?).
Well, what happens when you run the code? Does it change if you compile in 32 or 64 bit mode, if you have the facility?
What's happening is that you're asking the compiler to tell you the storage size (in bytes) needed to hold the tires variable. This variable has type TyreClass*, so the storage size is that needed for a data pointer: this might be anything, but today it will probably be 4 bytes for a 32-bit system, or 8 bytes for a 64-bit system.
Whilst it's possible to use sizeof to tell you the size of a statically allocated array, it's not possible for dynamic (heap) allocation. The sizeof operator (in C++, at least) works at compile time, whereas dynamically allocating memory is done when your programme runs.
Much better, for all sorts of reasons, would be to use a std::vector<TyreClass> to hold your tyres. You can then easily get the number of tyres stored, and don't have to worry about allocating or deallocating arrays yourself.
(EDIT: Gah, forgive me mixing up english/american spellings of tyre/tire. It's late and I'm tyred.)

C++ What is the right way of declaring a char array in a class?

This is kind of pseudo code but it should make clear what I want to know. I see all 3 variants in different code.
My question is which is the correct way of doing this and why? (Also see comments in code snippets)
test.h First way:
class Test {
public:
Test()
:_buffer(NULL)
{
_buffer = new char[1024];
}
~Test() {
delete _buffer;
}
int Function() {
//use some function like inet_ntop doesn't work _buffer is not filled
inet_ntop(p->ai_family, addr, _buffer, sizeof(_buffer)-1);
//here sizeof(_buffer) returns 4, WHY ?
cout << sizeof(_buffer) << endl;
}
private:
char *_buffer;
};
test.h Second way:
class Test {
public:
Test() {
//_buffer is never initialized WHY ?
}
~Test() {
//_buffer is never deleted WHY ?
}
int Function() {
//use some function like inet_ntop works correctly here _buffer is filled
inet_ntop(p->ai_family, addr, _buffer, sizeof(_buffer)-1);
//here sizeof(_buffer) returns 1024, WHY ?
cout << sizeof(_buffer) << endl;
}
private:
char _buffer[1024];
};
test.h Third way:
class Test {
public:
Test() {
}
~Test() {
}
int Function() {
char buffer[1024];
//use some function like inet_ntop works correctly here _buffer is filled
inet_ntop(p->ai_family, addr, _buffer, sizeof(_buffer)-1);
//here sizeof(_buffer) returns 1024
cout << sizeof(_buffer) << endl;
}
private:
};
C++ What is the right way of declaring a char array in a class?
Neither.
In C++ the correct way is to use:
std::string buffer;
This is precisely the reason C++ provides std::string. It gives you freedom from:
explicitly managing memory as in #1 &
overwriting the bounds of statically allocated array as in #2.
Note that the 3 examples you show are not equivalent.
#1 & #2 bind the lifetime of the character buffer to your object instance,
While #3 does not do the same.
Note that if you need a local buffer(who's size is fixed) just to pass to an c-style api, then that usage doesn't make good use of the goodies offered by std::string and probably a statically allocated character array is much more suitable.
If your requirement is as in #1 and #2 then the better option is ofcourse std::string.
First variant: character array is allocated from the heap. IIRC, the delete in the destructor should be delete [] _buffer.
Second variant: character array is part of the class, and lives and dies with the class. Could be allocated from the heap or stack, depending on how the class is instantiated.
Third variant: character array is allocated on the stack, and is released when the enclosing scope — in this case, Function() — ends.
Having said that, unless you really do need an array of characters for a justifiable reason, using std::string is far better.
I don't believe there is a "one true way" for what you are trying to do. Each of the methods involve a trade off. Specifically:
Method 1) You allocate memory on the heap. You incur a (slight) performance penalty. However, the size of your class in memory is reduced. If you allocate your class on the stack, you waste less stack space this way. As others have mentioned, you need to use the delete [] statement.
Regarding your comment, sizeof(buffer) returns 4 because buffer is a char pointer. Your platform defines pointers to be 4 bytes big. It doesn't report the size of the allocated array, as sizeof works on the type described to it. inet_ntop doesn't fill your buffer as you tell it your buffer is only 4 bytes big. inet_ntop simply fails as that buffer is much to small.
Method 2) This trades method 1's extra heap allocation for increased class size.
Regarding comments, the buffer is not initialized or deleted because C++ handles that. Since you instructed the compiler to provide you with a char array of size 1024 bytes, it provides you with one. You are not required to initialize/cleanup for the compiler. Also, sizeof returns 1024 as the type is a char array of 1024 bytes, thus the compiler know this and gives the array size. It doesn't return the size of a pointer here because you didn't ask for a pointer.
Method 3) This method instead allocates the buffer every time the function is called, and puts it on the stack. Depending upon what you intend to do with the data, this might be the best solution, or not applicable at all. If you don't need the buffer after the function ends, then it's a good choice.

dynamic array in structure with consecutive memory?

struct Test
{
int var;
char *arr;
}
int main()
{
Test a;
a.arr = new char[50];
}
The above code would create a dynamic array in the structure but the dynamic array would not be actually memory allocated within the structure, its memory would be allocated somewhere else. I want this array to be allocated in the structure as with the fixed array but I don't want to use fixed array. Any ideas?
I've tried my best to clarify my question, hope you understand.
I want to send this structure through UDP and UDP takes continues memory buffer to send that's why I want this structure to have continuous memory.
You can not do that as the new memory is from heap/ free store and your a will be allocated on stack....
you can allocate using malloc/new a continous memory block of sizeof Test + your required size and make the pointer arr to point at the end of the Test structure.
If you need it in function scope on stack you can use alloca.
Test *a = (Test*)alloca(sizeof(Test)+yoursize);
a->arr = (char*)a+sizeof(Test)...
No you cannot have variable length arrays in C++.
So you cannot do that.
You can have a fixed length array or you can use the approach you have given.
Another approach is,
You can use placement new to place your array at an pre-allocated memory location. This memory could be on stack.
Your code don't compile. You should compile it with all warnings enabled, and improve it till you got no warnings. And are your studying C or C++? If it is C++, consider using std::vector
struct Test {
int var;
char arr[1];
};
int main()
{
std::vector<char> buf;
buf.resize(sizeof(Test) + 50);
Test *foo = reinterpret_cast<Test *>(&buf[0]);
foo->arr[40] = 'b';
}
You can pass array size to structs constructor and allocate memory for array there. Don't forget to deallocate it somewhere, e.g. in destructor:
struct Test
{
int m_var;
char *arr;
public:
Test(int var) : m_var(var)
{
arr = new char[m_var];
}
~Test()
{
delete[] arr;
arr = 0;
}
};
void main(int argc, char* argv[])
{
Test t(50);
return 0;
}
Although it hasn't been "blessed" like it has in C, most compilers will still let you use the "struct hack":
struct variable_array {
size_t size;
char data[1];
};
The "trick" is that when you allocate it, you allocate enough space for the data you want to store (but this means it must be dynamically allocated):
variable_array *a = (variable_array *) ::operator new(sizeof(*a) + data_size);
a->size = data_size;
In theory, this isn't required to work -- the compiler could do a bound-check on references to the data member to ensure you don't index beyond the one element you've defined it to hold in the struct definition. In reality, I don't know of a single compiler that does such a thing, and kind of doubt that such a thing exists. Quite a lot of C code has done things like this for years, so a compiler that did such a check just wouldn't work with a lot of real-world code, even though the standard allows it. C99 also adds this (with minutely different syntax) as an official feature of the language.
Bottom line: it's a bit clumsy, but the possibility of really not working is almost entirely theoretical.
Not truly dynamic allocation, but might solve your problem (depends on if you always know the desired size of the array at compile time)
template <size_t ArraySize>
struct Test
{
int var;
char arr[ArraySize];
}
int main()
{
Test<50> a;
}

Array allocation - can you stop constructors and destructors from being called?

I'm in the unfortunate position to write my own vector implementation (no, using a standard implementation isn't possible, very unfortunately). The one which is used by now uses raw bytes buffers and in-place construction and deconstruction of objects, but as a side-effect, I can't look into the actual elements. So I decided to do a variant implementation which uses internally true arrays.
While working on it I noticed that allocating the arrays would cause additional calls of construtor and destructor comapred to the raw buffer version. Is this overhead somehow avoidable without losing the array access? It would be nice to have it as fast as the raw buffer version, so it could be replaced.
I'd appreciate as well if someone knows a good implementation which I could base my own on, or the very least get some ideas from. The work is quite tricky after all. :)
Edit:
Some code to explain it better.
T* data = new T[4]; // Allocation of "num" elements
data[0] = T(1);
data[1] = T(2);
delete[] data;
Now for each element of the array the default constructor has been called, and then 2 assignment methods are called. So instead just 2 constructor calls we have 4 and later 4 destructor calls instead just 2.
as a side-effect, I can't look into the actual elements.
Why not?
void* buffer = ...
T* elements = static_cast<T*>(buffer);
std::cout << elements[0] << std::endl;
Using true arrays means constructors will be called. You'll need to go to raw byte buffers - but it's not too bad. Say you have a buffer:
void *buffer;
Change that to a T *:
T *buffer;
When allocating, treat it as a raw memory buffer:
buffer = (T *) malloc(sizeof(T) * nelems);
And call constructors as necessary:
new(&buffer[x]) T();
Your debugger should be able to look into elements of the buffer as with a true array. When it comes time to free the array, of course, it's your responsibility to free the elements of the array, then pass it to free():
for (int i = 0; i < nInUse; i++)
buffer[x].~T();
free((void*)buffer);
Note that I would not use new char[] and delete[] to allocate this array - I don't know if new char[] will give proper alignment, and in any case you'd need to be careful to cast back to char* before delete[]ing the array.
I find the following implementation quite interesting: C Array vs. C++ Vector
Besides the performance comparison, his vector implementation also includes push/pop operations on the vector.
The code also has an example that shows how to use the macros:
#include "kvec.h"
int main() {
kvec_t(int) array;
kv_init(array);
kv_push(int, array, 10); // append
kv_a(int, array, 20) = 5; // dynamic
kv_A(array, 20) = 4; // static
kv_destroy(array);
return 0;
}