std::set for each element in an array - c++

I need a functionality of std::set for each element in an array. How can I achieve this functionality?
I started with allocating dynamic array of std set in C++ as follows:
set<int>* entry;
followed by allocation:
entry = (set<int>*)malloc(sizeof(set<int>)*32);
No compilation problem, but the runtime fails with segmentation fault when any element is accessed:
entry[0].insert(23);
Any help is highly appreciated.

What about
#include <set>
#include <vector>
int main()
{
std::vector < std::set<int> > entry(32); // std::vector constructor makes 32 calls to std::set<int> constructor
entry[0].insert(23);
// std::vector destructor makes 32 calls to std::set<int> destructor
}

In c++ you allocate memory with new. The difference from malloc here is that the constructor is called to initialize the memory.
entry = new set<int>[32];

Even though you've allocated storage for 32 std::set's you haven't initalized this span of memory (ie. the constructor of your std::set's has not been called) therefore the memory you are trying to operate on/access in entry[0].insert (23) will cause undefined behavior.
Mixing C++ objects with malloc and it's equivalent is normally (I'm tempted to write "always") considered to be bad practice.
Instead turn to operator new which will allocate memory and handle construction of your object in a proper manner, also remember to delete the memory allocated to release the memory back to your system (and make the object(s) destruct in a true manner).
The proper way to do it in C++
Some answers will contain text saying that you are better of using a std::vector<std::set>, though that isn't really an answer to your question so I'll leave you with this example snippet
int
main (int argc, char *argv[])
{
std::set<int> *entries = new std::set<int> [32];
entries[0].insert (123);
delete [] entries;
}

This is a good question, whose answer is not immediately obvious. The trouble is that each set object wants to be initialized before it is used, whereas your code only allocates raw memory for each set. This fixes it:
#include <vector>
#include <set>
using std::vector;
using std::set;
const int N = 32;
int main() {
vector< set<int> > entry(N);
entry[0].insert(23);
return 0;
}

Not try to use malloc/calloc/realloc etc with c++ classes. Use new.

Related

Convert malloc to new

How to write the following code using new operator?
Please explain in detail.
Thanks in advance.
#include<alloc>
#define MAXROW 3
#define MAXCOL 5
using namespace std;
int main()
{
int (*p)[MAXCOL];
p = (int(*)[MAXCOL])malloc(MAXROW*sizeof(*p));
}
Quite simply, to answer the question literally:
p = new int[MAXROW][MAXCOL];
This allocates a 2D array (MAXROW by MAXCOL) on the free store and, as usual with new, returns a int(*)[MAXCOL] - the same type as decaying the 2D array. Don't forget to delete[] p;.
The last part brings up the importance of std::vector. Presumably, you know the size of the second dimension at compile-time. Therefore, a std::vector<std::array<int, MAXCOL>> would work with the added bonus of not requiring a delete[] statement, plus it knows its size (MAXROW). Please use this if at all possible.
In fact, in your example, both dimensions are known at compile-time, meaning a std::array<std::array<int, MAXCOL>, MAXROW> would also work here. That's typically preferable to dynamic allocation.
If neither dimension is known at compile-time, your best bet is usually a vector of vectors or a dedicated matrix class to increase performance when you know every inner vector is the same size.
Since this is C++ I will recomend using std::array and std::unique_ptr
Also when using malloc you should use free un-alloc or free the memory, if you use new you need to use delete; if you new[] you need to use delete[]
#include <cstdlib>
#include <memory>
#include <array>
#define MAXROW 3
#define MAXCOL 5
using namespace std;
int main()
{
int (*p)[MAXCOL];
p = (int(*)[MAXCOL])malloc(MAXROW*sizeof(*p));
free(p); //free memory
array<int,MAXCOL> *p1 = new array<int,MAXCOL>[MAXROW];
delete []p1; //use this to delete the variable
array<array<int,MAXCOL>,MAXROW> *p2 = new array<array<int,MAXCOL>,MAXROW>;
delete p2; // normal delete for this one
auto p3 = make_unique<array<array<int,MAXCOL>,MAXROW>>();
//no delete needed for p3, it is a smart pointer.
}
The literal question
” How to write the following code using new operator?
… means something else than you think it means.
The new operator is a simple allocation function roughly directly analogous to C's malloc, except the C++ new operator is replacable by a user defined one.
You probably mean a new expression. Such an expression invokes the new operator for allocation, and then invokes a constructor for initialization, if the allocated thing is of class type. And it's type safe.
Still, for your array you'd not want that either, but simply std::vector from the standard library.
Here's an example using a std::vector of vectors to create a matrix:
#include <vector>
using namespace std;
auto main()
-> int
{
int const n_rows = 3;
int const n_cols = 5;
using Row = vector<int>;
vector<Row> v( n_rows, Row( n_cols ) );
// E.g. v[1] is a row, and v[1][2] is an int item in that row.
}
Even if you don't so often use matrices, it can be a good idea to wrap the general notion of a matrix, in a class. A simple way is to use a single std::vector for storage, and provide e.g. an at function or an operator() for indexing from client code. If you don't yet feel like doing this yourself, then e.g. the Boost library provides a matrix class.

How to avoid memory leaks, with C++ with STL containers?

code snippet below:
//container declared
map<string, structA*>& aMap;
// allocation and insertion to container
structA *item = new structA();
aMap["arrDevAddr"] = item;
However I iterate and free the map value (pointer) at the end of the map getting used.
Now, due to above code snippet, valgrind is flagging me as "definitely leaked" message.
I want to clarify, the general principle of coding to avoid memory leak. As per my understanding, in (C++ coding):
when we allocate a memory, we are entitled to free it aswell, limted by the overall span of code.
when we keep the allocated memory in some container (e.g. map here), we still need to retain those pointers (allocations), until the map is using those pointers.
which means, allocate >> add pointer to container >> usage of pointers in the map >> ensure "deleting/freeing" the struct-pointers, when the map use is over, or if the map is contained in some object, then in the object's "destructor", map should be iterated and struct-pointers should be freed.
correct me, if I am wrong in my understanding.
SECOND CASE:
class A{
...
map<string, structA*>& aMap;
...
}
now in some other class, the map is inserted with value as;
if(..)
{ structA item;
aObj->aMap["arrDevAddr"] = &item;
}
...
Now, in this case, as "item" is local to the scope, will the map be containing the "dangling references"? If not, how?
In such scenario's what should be the way to ensure, we avoid any memory-leaks while coding?
Don't delete or free things yourself. Always use a memory-managing class- these are completely immune to memory leaks and such related problems unless you work very hard to do something very stupid.
In this case something like unique_ptr would be fine, or even just storing structA by value.
You would avoid memory leaks by storing a std::unique_ptr rather than a raw pointer:
#include <iostream>
#include <map>
#include <memory>
#include <string>
struct structA {};
using structA_ptr = std::unique_ptr<structA>;
//container declared
std::map<std::string, structA_ptr> aMap;
using namespace std;
int main()
{
aMap.emplace("bob", structA_ptr { new structA {} });
return 0;
}

C++ dynamic array size definition

I am used to java and php and now I need to write some c++ code. I got difficulties to create a BYTE-array with dynamic size. How to achieve this?
int byteSize = shm.getMemorySize();
BYTE byte[44]; // replace 44 by byteSize
You should use std::vector unless you have very specific reason to use arrays. Normally, in the similar context where you were using arrays in other languages in C++ the default choice should be std::vector.
Never use a naked pointer or it is open door for bugs and memory leaks, instead, here some alternatives :
int len = something;
std::vector<char> buffer(len,0);
or c++11 smart pointer
std::unique_ptr<char[]> buffer{ new char[len] };
or c++14 with make_unique
auto buffen = std::make_unique<char[]>(len);
Use a vector, unless you absolutely need to handle memory yourself. Also, this is more of a preference thing, but I prefer to use uint8_t instead of BYTE. Its a bit more compliant as it doesn't depend on GCC.
#include <vector>
#include <cstdint>
...
std::vector<uint8_t> foo;
or
#include <cstdint>
...
uint8_t* data;
data = new uint8_t[10];
...
delete[] data;
You can use the STL standard container class std::vector to have a dynamic resizable array:
#include <vector> // For std::vector
....
int byteSize = shm.getMemorySize();
// Create a vector of 'byteSize' bytes.
std::vector<BYTE> bytes(byteSize);
You can access vector elements using the usual [] syntax (e.g. bytes[0], bytes[1], ...bytes[i]).
vector's destructor will automatically release the memory allocated by the vector, so you don't have to pay attention to freeing memory.
You can use vector's push_back() method to add items at the end of the vector (with automatic resizing).
You can use vector's clear() method to empty it.
And vector's size() method returns the current number of items in the vector.
If you want to learn more about std::vector, you can watch this great introductory video by Stephan T. Lavavej.
One way to do it is to use dynamic memory allocation with new
BYTE* data = new BYTE[byteSize];
data[0] = 0;
delete [] data;
However this approach in the hands of a beginner can lead to memory corruptions, crashes, memory leaks, and all sorts of behaviors that are hard to find and fix.
A better way is to use std::vector that is almost safe against the problems the first approach has:
std::vector<BYTE> data;
data.resize(byteSize);
data[0] = 0;
You can create the dynamic array as follows:
int byteSize = shm.getMemorySize();
BYTE* byte = new BYTE[byteSize];
//Use the byte
delete [] byte;

C++ Allocate Memory Without Activating Constructors

I'm reading in values from a file which I will store in memory as I read them in. I've read on here that the correct way to handle memory location in C++ is to always use new/delete, but if I do:
DataType* foo = new DataType[sizeof(DataType) * numDataTypes];
Then that's going to call the default constructor for each instance created, and I don't want that. I was going to do this:
DataType* foo;
char* tempBuffer=new char[sizeof(DataType) * numDataTypes];
foo=(DataType*) tempBuffer;
But I figured that would be something poo-poo'd for some kind of type-unsafeness. So what should I do?
And in researching for this question now I've seen that some people are saying arrays are bad and vectors are good. I was trying to use arrays more because I thought I was being a bad boy by filling my programs with (what I thought were) slower vectors. What should I be using???
Use vectors!!! Since you know the number of elements, make sure that you reserve the memory first (by calling myVector.reserve(numObjects) before you then insert the elements.).
By doing this, you will not call the default constructors of your class.
So use
std::vector<DataType> myVector; // does not reserve anything
...
myVector.reserve(numObjects); // tells vector to reserve memory
You can use ::operator new to allocate an arbitrarily sized hunk of memory.
DataType* foo = static_cast<DataType*>(::operator new(sizeof(DataType) * numDataTypes));
The main advantage of using ::operator new over malloc here is that it throws on failure and will integrate with any new_handlers etc. You'll need to clean up the memory with ::operator delete
::operator delete(foo);
Regular new Something will of course invoke the constructor, that's the point of new after all.
It is one thing to avoid extra constructions (e.g. default constructor) or to defer them for performance reasons, it is another to skip any constructor altogether. I get the impression you have code like
DataType dt;
read(fd, &dt, sizeof(dt));
If you're doing that, you're already throwing type safety out the window anyway.
Why are you trying to accomplish by not invoking the constructor?
You can allocate memory with new char[], call the constructor you want for each element in the array, and then everything will be type-safe. Read What are uses of the C++ construct "placement new"?
That's how std::vector works underneath, since it allocates a little extra memory for efficiency, but doesn't construct any objects in the extra memory until they're actually needed.
You should be using a vector. It will allow you to construct its contents one-by-one (via push_back or the like), which sounds like what you're wanting to do.
I think you shouldn't care about efficiency using vector if you will not insert new elements anywhere but at the end of the vector (since elements of vector are stored in a contiguous memory block).
vector<DataType> dataTypeVec(numDataTypes);
And as you've been told, your first line there contains a bug (no need to multiply by sizeof).
Building on what others have said, if you ran this program while piping in a text file of integers that would fill the data field of the below class, like:
./allocate < ints.txt
Then you can do:
#include <vector>
#include <iostream>
using namespace std;
class MyDataType {
public:
int dataField;
};
int main() {
const int TO_RESERVE = 10;
vector<MyDataType> everything;
everything.reserve( TO_RESERVE );
MyDataType temp;
while( cin >> temp.dataField ) {
everything.push_back( temp );
}
for( unsigned i = 0; i < everything.size(); i++ ) {
cout << everything[i].dataField;
if( i < everything.size() - 1 ) {
cout << ", ";
}
}
}
Which, for me with a list of 4 integers, gives:
5, 6, 2, 6

C++ memory management for a vector with variable length items

Take a variable length struct (if this were a real program, an int array would be better):
#include <vector>
struct list_of_numbers(){
int length;
int *numbers; //length elements.
};
typedef std::vector<list_of_numbers> list_nums; //just a writing shortcut
(...)
And build a vector out of it:
list_nums lst(10); //make 10 lists.
lst[0].length = 7; //make the first one 7 long.
lst[0].X = new int[7]; //allocate it with new[]
(...)
The above works for g++ in ubuntu. The new() calls are needed to avoid segfaults. Can the lst vector be deleted all at once when it is no longer needed, or will the new calls cause a memory leak? It would be tedious to manually delete() all of the parts called with new().
The typical ways to do this in C++ would be to define constructors and destructors and assignment operators for the list_of_numbers struct that take care of the memory management, or (much better) use a std::vector<int> for the numbers field and get rid of the length field.
But if you do that, you may as well get rid of the struct entirely, and just do this:
#include <vector>
typedef std::vector<int> list_ints;
typedef std::vector<int_ints> list_lists;
(...)
list_lists lst(10); // make 10 lists.
lst[0].resize(7); // set length of the zeroth list to 7
Why not just use a vector of vector of int? That's it's job. You should not be calling new outside of a dedicated class.
In general, you would want to put cleanup code in the destructor of the object (~list_of_numbers()) and memory creating code in the constructor (list_of_numbers()). That way these things are handled for you when the destructor is called (or when the object is created).