I have written a code using global heap. I need to redo the same operation a number of time. Every time I need to clear the heap and re-assign the data. but the vector::clear() function does not free the memory. so after some time the memory gets filled and the program terminates.
#include "stdafx.h"
#include <cstdio>
#include <vector>
using namespace std;
#define N 30000
typedef unsigned int uint;
class Node;
class Edge;
vector<Node*> nodes;
vector<Edge*> edges;
class Node
{
public:
Node(uint id): id(id)
{
nodes.push_back(this);
}
public:
uint id;
};
class Edge
{
public:
Edge(int nod1, int nod2)
: nodH(nod1), nodT(nod2)
{
edges.push_back(this);
}
bool Connects(Node* nod1, Node* nod2)
{
return (
(nod1->id == this->nodH && nod2->id == this->nodT) ||
(nod1->id == this->nodT && nod2->id == this->nodH));
}
public:
int nodH;
int nodT;
};
int _tmain(int argc, _TCHAR* argv[])
{
Node *nd;
for(long int i=0;i<N;i++)
{
for (int j=0;j<N;j++)
{
nd = new Node(j);
}
for (uint j=0;j<N;j++)
{
Edge* e = new Edge(j,N-j);
}
printf("%d %d ",nodes.size(),edges.size());
// Do something here like calling function etc.
nodes.erase(nodes.begin()+N/2);
nodes.clear();
edges.clear();
//nodes.~vector();
//edges.~vector();
printf("%d %d\n",nodes.size(),edges.size());
}
getchar();
return 0;
}
what can I do? I tried the vector::~vector() function. But that did not work.
Can anyone help me about how to free the "cleared" memory space?
Well known trick is to swap your vector with temporary created one
template< class T >
void clearVector( std::vector< T > & v )
{
std::vector< T > dummy;
std::swap( v, dummy );
}
BTW, using vector with raw pointers isn't a good idea. I'll suggest std::shared_ptr or similar. If (in some amazing reasons) you can't use smart pointers, then you should call function like this
struct die {
template <class T> void operator()( const T * p ) const { delete p; }
};
template< class InputIterator >
inline void kill_em_all( const InputIterator & begin, const InputIterator & end )
{
std::for_each( begin, end, die() );
}
...
kill_em_all( vector_to_clear.begin(), vector_to_clear.end() );
The reason vector.clear() does not delete the objects is that you keep raw pointers in the two vectors:
vector<Node*> nodes;
vector<Edge*> edges;
You either have to deallocate the elements yourself or, better, use smart pointers (for example, std::unique_ptr).
You are assigning one giant heap of memory for your application. Try to reduce your N to 100 for the start. bad_alloc usually means, that the runtime was not able to reserve memory.
Related
I have a class A with a member vector<class B>. I would like to loop through this vector from outside class A in a clean way. I need to do operations on B using its public functions.
To do so, I thought of having a function int get_next_element(B * in_B), where I can return 0 if I have correctly loaded the next element and -1 otherwise.
I thought of doing this by using an iterator, but I found two issues with this. First of all, I wasn't able to find a neat way to convert an iterator to a pointer (it seems I could use an iterator just like a pointer, but I'm unsure that's a good solution). Secondly, I would need to check if there's a value referenced by my iterator, and since the closest thing to a "null iterator" is the .end() element I can't figure out how I would then initialise it. If I initialise it (empty) and have the reference .end(), it wont refer to anything comparable if I add something to it.
I could have an extra int that keeps track of which element I'm at, but then I'd have to manage that int whenever I add elements, etc.
I considered placing the iteration code outside of class A, but I may need to change or access individual elements during the loop, so that would make a complex/big iteration block.
How would I solve this problem in a clean way (such as int get_next_element(B * in_b))?
EDIT:
Here's some code:
Header:
class B {
public:
B();
void set_size(int in_size);
int get_size();
protected:
int mSize;
};
class A {
public:
A();
void add_B(B in_B);
int get_next_element(B * in_B);
protected:
std::vector<B> mObjects;
};
cpp file:
B::B() {
// Stuff
}
void B::set_size(int in_size) {
mSize = in_size;
}
int B::get_size() {
return mSize;
}
A::A() {
// Stuff
}
void A::add_B(B in_B) {
mObjects.push_back(in_B);
}
int A::get_next_element(B * in_B) {
// ToDo : handle elements
}
And main:
int main() {
A test_a;
for (int i = 0; i < 5; i++) {
B tmp_b;
tmp_b.set_size(i);
test_a.add_B(tmp_b);
}
B iterator_b;
while (0 == get_next_element(& iterator_b)) {
if (iterator_b.get_size > 2) {
B tmp_b;
tmp_b.set_size(iterator_b.get_size - 2);
test_a.add_B(tmp_b);
iterator_b.set_size(2);
}
}
}
So, basically A holds a bunch of Bs and can help the main iterate through them and (in this example) cut them into smaller pieces while not having too much code in the main. There's quite a few dimensions/ways this will be done, which is partially why I'd like to "hide" as much of the code in A.
(This is a bit simplified, like the Bs may have to have internal relations, but basically that's the idea)
Consider using a range-base for loop (C++1x).
class A {
private:
std::vector<class B> vec;
public:
std::vector<class B>& get_vec() { return vec; }
};
A a_instance;
for (B &b : a_instance.get_vec()) {
b.print();
std::cout << "b = " << b << std::endl;
std::cout << "&b = " << &b << std::endl;
}
This, unfortunately, does not allow looking ahead, unless you keep track of index yourself.
this is what I mean...
#include <iostream>
#include <vector>
class B {
public:
B(int in) :mSize(in) {}
size_t mSize;
void set_size(int in_size) { mSize = in_size;}
int get_size() {return mSize;}
};
class A {
using container = std::vector<B>;
using iterator = container::iterator;
container mObjects;
public:
void add_B(B in_B) { mObjects.push_back(in_B); }
iterator begin() { return mObjects.begin(); }
iterator end() { return mObjects.end(); }
};
int main() {
A test_a;
for (int i = 0; i < 5; i++) {
test_a.add_B(B(i));
}
for( auto& item : test_a)
if (item.get_size() > 2) {
B tmp_b(item.get_size() - 2);
item.set_size(2);
test_a.add_B(tmp_b);
break;//if using a vector, must break as vector can change/reallocate on 'add_B()'
}
}
I am trying to swap the content in the arrays by swapping the pointers pointing to the two arrays.
My method is the same as what Daniel answered in this question: Swap arrays by using pointers in C++. But the difference is that my array will be a member in a class.
My code can be compiled successfully, but the output results are quite weird.
This is my header file:
#include <stdio.h>
#include <iostream>
class Map
{
public:
Map(int times); // Create an empty map (i.e., one with no key/value pairs)
int size(); // Return the number of key/value pairs in the map.
void dump();
void swap(Map &other);
int *retrieve();
void setptr(int *newptr);
private:
int *ptr;
int array_1[5];
};
Here is my implementation:
#include "Map.h"
#include <iostream>
using namespace std;
Map::Map(int times) {
for (int i = 0; i < 5; i++) {
array_1[i]=i*times;
}
ptr=array_1;
}
void Map::dump() {
ptr=array_1;
for (int i = 0; i < 5; i++) {
cout << *ptr << endl;
ptr++;
}
for (int i = 0; i < 5; i++) {
ptr--;
}
}
void Map::swap(Map &other) {
int *temp;
temp = this->ptr;
this->ptr = other.retrieve();
other.setptr(temp);
}
int *Map::retrieve() {
return ptr;
}
void Map::setptr(int *newptr) {
ptr=newptr;
}
Can anyone tell me what is wrong and how to implement it smartly?
The following code runs fine:
#include <stdio.h>
#include <iostream>
#include <conio.h>
using namespace std;
class Map
{
public:
Map(int times); // Create an empty map (i.e., one with no key/value pairs)
int size(); // Return the number of key/value pairs in the map.
void dump();
void swap(int &other);
int *retrieve();
void setptr(int *newptr);
private:
int *ptr;
int array_1[5];
};
Map::Map(int times){
for (int i=0;i<5;i++){
array_1[i]=i*times;
}
ptr=array_1;
}
void Map::dump(){
for (int i=0;i<5;i++)
{
cout<<ptr[i]<<endl;
}
}
void Map::swap(int &other){
int *temp;
temp=this->ptr;
this->ptr=&other;
other = *temp;
}
int *Map::retrieve(){
return ptr;
}
void Map::setptr(int *newptr){
ptr=newptr;
}
int main()
{
Map m(2);
Map n(3);
m.dump();
m.swap(*n.retrieve());
m.dump();
getchar();
}
1) Added a main function
2) Changed Swap function
But the problem that christopher pointed out will still persist i.e the pointer will point to an array in another object.
Edit: You probably need something like this:
void Map::swap(Map &other){
Map *temp;
temp=this;
*this = other;
other = *temp;
}
Map *Map::retrieve(){
return this;
}
Note: it is probably not elegant.
The problem with your design is that the pointer refers to an array in the same object.
Suppose you have to objects a and b. If you swap their pointers, a.ptr will point to b.array_1 which contains the data. reciprocally b.ptr will point to a.array1.
Unfortunately if one of the object -- say b -- gets destroyed (because it was a local object that goes out of scope, or for whatever reason) the pointer of the remaining object would point to an array which doesn't exist anymore. This is UB.
To solve your issue, you'd neet to allocate an array dynamically in the constructor. Get rid of array_1 completely:
Map::Map(int times){
ptr=new int[5]; // or better define a constant to avoid hard coded sizes
for (int i=0;i<5;i++){
ptr[i]=i*times;
}
}
Note that if you use pointers, you need to ensure the invarients on it. This means that you should define also the copy constructor and the assignment operator (to avoid the ptr to be blindly copied), as well as a destructor (to delete the dynamically allocated array).
P.S.: I suppose that you are learning C++ and are not yet familiar with vectors. These would avoid all the hassles here
Edit: if you experience your problem before any object is destroyed, it's because of a bad implementation of dump(): you increment the pointer there in, so that it will no longer point to the start of the array.
void Map::dump(){
for (int i=0;i<5;i++){
cout<<ptr[i]<<endl; // don't change ptr value !!
}
}
One simple trick to avoid such problems, is to systematically declare the member functions that are not supposed to change the state of the object as const:
class Map {
...
void dump() const;
...
}
Then the compiler issues an error if you try to accidentally change a member.
I have tried looking around and tried all the solutions but I cannot seem to fix my problem. I know i get the segmentation fault on the push_front line but I am just lost. Here is the code-
#include <iostream>
#include <fstream>
#include <sstream>
#include <list>
using namespace std;
typedef std::list<int> hSlots; //the list
typedef hSlots* hTable; //an array of lists
class HashTable
{
private:
int p; //p=number of slots in the hash table
hTable tmpPtr;
hTable *table;
public:
HashTable(int p1);
int h1(int k);
~HashTable();
void chainedHashInsert(int x);
};
HashTable::HashTable(int p1)
{
p=p1;
hTable tTable[p];
//initializing to empty lists
for (int i=0; i<p; i++)
{
tmpPtr = new hSlots;
tTable[i] = tmpPtr;
}
table = tTable;
}
//destrcutor
HashTable::~HashTable()
{
delete table;
delete tmpPtr;
}
void HashTable::chainedHashInsert(int x)
{
tmpPtr = table[h1(x)];
cout<<"hashed"<<endl;
tmpPtr->push_front(x); //segmentation fault
}
int HashTable::h1(int k)
{
int z = k%p;
return z;
}
I have not used a lot of lists so I'm not too sure
Maybe this could be a proper answer after all.
Your problems arise from doing memory management (wrong) manually, when really there is no need to, in C++.
Here's my take on it using direct automatic memory management in C++:
#include <vector>
#include <list>
using namespace std;
template <typename T, typename hSlots = std::list<T> >
class HashTable
{
private:
int p; //p=number of slots in the hash table
std::vector<hSlots> table;
int getbucket(int k) { return k%p; }
public:
HashTable(int p1) : p(p1), table(p1) {}
void chainedHashInsert(int x)
{
auto& tmpPtr = table[getbucket(x)];
tmpPtr.push_front(x);
}
};
int main()
{
HashTable<int> table(37);
}
since tTable is local variable to HashTable, it disappears when HashTable method returns and leaves table as a dangling pointer.
So to get rid of that do as below; create a space for table using new.
HashTable::HashTable(int p1)
{
p=p1;
table = new ttTable[p];
//initializing to empty lists
for (int i=0; i<p; i++)
{
tmpPtr = new hSlots;
table[i] = tmpPtr;
}
}
table = tTable;
This line is the problem (or at least one of them).
You're stashing a pointer to an automatic object into a member variable, then dereferencing (and deleting!) it later, once the object has been destroyed.
I added a large number of elements and then deleted them all in a boost::unordered_map.
Then I saw the memory held by this program is 198MB (greater than (64+4)*2M) and the unordered_map size is 0.
I then test a vector, and there is no such problem. Why?
#include <iostream>
#include <boost/unordered_map.hpp>
template <int N>
struct big_struct {
char c[N];
};
int main(void) {
typedef big_struct<64> data_type;
typedef boost::unordered_map<int, data_type*> map_type;
map_type m;
for (int i = 0; i < 2000 * 1000; i++) {
m.insert(std::make_pair(i, new data_type));
}
for (map_type::iterator it = m.begin(); it != m.end();) {
delete it->second;
it = m.erase(it);
}
std::cout << "finish, map size " << m.size() << std::endl;
pause();
return 0;
}
The language runtime holds on to the allocated memory, assuming that you might want to use it again. Returning millions of small blocks to the OS would take quite some time, and make your program run slower.
If you have a very large vector, that is still only a single memory block. Some compilers consider returning this kind of memory when it is not needed anymore. Returning one large block is considerably more efficient than a million small blocks.
This is one clear example of what happens when boost become a standard part of C++.
std::unordered_map
is effectively lacking control on releasing memory, the above answer is not correct.
A std::unordered_map may not release any memory until a rehash happens. When a rehash may happen is documented, if you look at size() documentation it just says it is the number of elements, if you want an Idea of the real size you have to add a custom allocator inside the map and count allocated/deallocated bytes.
This is a pity because since the behaviour is not documented (there's not either some API to control that) you don't know if implementation free memory (good if you are going to not use the map for a while), or if implementation cache memory (good if you are going to insert again different elements).
This make using in a memory efficient way the unordered_map very hard. Also this basically leave room for huge memory usage without being documented (it is not stated anywhere that a map with NO ELEMENTS could take several hundreds megabytes)
Here's a custom allocator that profile memory usage
#include <unordered_map> //c++ container but in practice the same of boost
#include <memory>
#include <iostream>
using namespace std;
size_t counter = 0;
template <typename T>
class countingAllocator: public std::allocator<T>
{
public:
typedef size_t size_type;
typedef T* pointer;
typedef const T* const_pointer;
template<typename _Tp1>
struct rebind
{
typedef countingAllocator<_Tp1> other;
};
pointer allocate(size_type n, const void *hint=0){
counter += n;
return std::allocator<T>::allocate(n, hint);
}
void deallocate(pointer p, size_type n){
counter -= n;
return std::allocator<T>::deallocate(p, n);
}
static size_t getAllocatedBytes() { return counter;}
countingAllocator() throw(): std::allocator<T>() {}
countingAllocator(const countingAllocator &a) throw(): std::allocator<T>(a) { }
template <class U>
countingAllocator(const countingAllocator<U> &a) throw(): std::allocator<T>(a) { }
~countingAllocator() throw() { }
};
template <int N>
struct big_struct {
char c[N];
};
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;
int main( int argc, char ** argv) {
typedef big_struct<64> data_type;
typedef std::unordered_map<int, data_type*, std::hash<int>, std::equal_to<int>,
countingAllocator< std::pair< const int, data_type*>> > map_type;
map_type m;
for (int i = 0; i < 1000 * 1000; i++) {
m.insert(std::make_pair(i, new data_type));
}
for (map_type::iterator it = m.begin(); it != m.end();) {
delete it->second;
it = m.erase(it);
}
std::cout << "allocated memory before returning " << countingAllocator< std::pair< const int, data_type*>> ::getAllocatedBytes() << std::endl;
return 0;
}
and the output of the program:
allocated memory before returning 1056323
So basically that means that you need to call the map destructor in some way to properly get rid of the memory allocated previously and you can do that in several ways:
put unordered_map into a shared_ptr
make unordered_map going out of scope
I uploaded the profile code on my PublicProfileTests repository so that you can contribute
I need to dynamically allocate 1-D and 2-D arrays whose sizes are given at run-time.
I managed to "discover" std::vector and I think it fits my purposes, but I would like to ask whether what I've written is correct and/or can be improved.
This is what I'm doing:
#include <vector>
typedef std::vector< std::vector<double> > matrix;
//... various code and other stuff
std::vector<double> *name = new std::vector<double> (size);
matrix *name2 = new matrix(sizeX, std::vector<double>(sizeY));
Dynamically allocating arrays is required when your dimensions are given at runtime, as you've discovered.
However, std::vector is already a wrapper around this process, so dynamically allocating vectors is like a double positive. It's redundant.
Just write (C++98):
#include <vector>
typedef std::vector< std::vector<double> > matrix;
matrix name(sizeX, std::vector<double>(sizeY));
or (C++11 and later):
#include <vector>
using matrix = std::vector<std::vector<double>>;
matrix name(sizeX, std::vector<double>(sizeY));
You're conflating two issues, dynamic allocation and resizable containers. You don't need to worry about dynamic allocation, since your container does that for you already, so just say it like this:
matrix name(sizeX, std::vector<double>(sizeY));
This will make name an object with automatic storage duration, and you can access its members via name[i][j].
What you're doing should basically work, however:
In general, don't dynamically allocate objects
If you want a vector, do this:
std::vector<double> vec(size);
not this:
std::vector<double>* vec = new std::vector<double>(size);
The latter gives you a pointer, which you have to delete. The former gives you a vector which, when it goes out of scope, cleans up after itself. (Internally, of course, it dynamically allocates objects, but the trick is that this is handled by the class itself, and you don't need to worry about it in your user code).
It is correct but could be made more efficient.
You could use the boost multidimensional arrays:
http://www.boost.org/doc/libs/1_47_0/libs/multi_array/doc/user.html
Or, you can implement your own class for it and handle the indexing yourself.
Perhaps something like this (which is not well tested):
#include <vector>
#include <cassert>
template <typename T, typename A = std::allocator<T> >
class Array2d
{
public:
typedef Array2d<T> self;
typedef std::vector<T, A> Storage;
typedef typename Storage::iterator iterator;
typedef typename Storage::const_iterator const_iterator;
Array2d() : major_(0), minor_(0) {}
Array2d(size_t major, size_t minor)
: major_(major)
, minor_(minor)
, storage_(major * minor)
{}
template <typename U>
Array2d(size_t major, size_t minor, U const& init)
: major_(major)
, minor_(minor)
, storage_(major * minor, u)
{
}
iterator begin() { return storage_.begin(); }
const_iterator begin() const { return storage_.begin(); }
iterator end() { return storage_.end(); }
const_iterator end() const { return storage_.end(); }
iterator begin(size_t major) {
assert(major < major_);
return storage_.begin() + (major * minor_);
}
const_iterator begin(size_t major) const {
assert(major < major_);
return storage_.begin() + (major * minor_);
}
iterator end(size_t major) {
assert(major < major_);
return storage_.begin() + ((major + 1) * minor_);
}
const_iterator end(size_t major) const {
assert(major < major_);
return storage_.begin() + ((major + 1) * minor_);
}
void clear() {
storage_.clear();
major_ = 0;
minor_ = 0;
}
void clearResize(size_t major, size_t minor)
{
clear();
storage_.resize(major * minor);
major_ = major;
minor_ = minor;
}
void resize(size_t major, size_t minor)
{
if ((major != major_) && (minor != minor_))
{
Array2d tmp(major, minor);
swap(tmp);
// Get minimum minor axis
size_t const dist = (tmp.minor_ < minor_) ? tmp.minor_ : minor_;
size_t m = 0;
// copy values across
for (; (m < tmp.major_) && (m < major_); ++m) {
std::copy(tmp.begin(m), tmp.begin(m) + dist, begin(m));
}
}
}
void swap(self& other)
{
storage_.swap(other.storage_);
std::swap(major_, other.major_);
std::swap(minor_, other.minor_);
}
size_t minor() const {
return minor_;
}
size_t major() const {
return major_;
}
T* buffer() { return &storage_[0]; }
T const* buffer() const { return &storage_[0]; }
bool empty() const {
return storage_.empty();
}
template <typename ArrRef, typename Ref>
class MajorProxy
{
ArrRef arr_;
size_t major_;
public:
MajorProxy(ArrRef arr, size_t major)
: arr_(arr)
, major_(major)
{}
Ref operator[](size_t index) const {
assert(index < arr_.minor());
return *(arr_.buffer() + (index + (major_ * arr_.minor())));
}
};
MajorProxy<self&, T&>
operator[](size_t major) {
return MajorProxy<self&, T&>(*this, major);
}
MajorProxy<self const&, T const&>
operator[](size_t major) const {
return MajorProxy<self&, T&>(*this, major);
}
private:
size_t major_;
size_t minor_;
Storage storage_;
};
While the points the other answers made were very correct (don't dynamically allocate the vector via new, but rather let the vector do the allocation), if you are thinking terms of vectors and matrices (e.g. linear algebra), you might want to consider using the Eigen matrix library.
You don't allocate containers dynamically. They can automatically manage memory for you if they themselves are not manually managed.
A vector grows when you add new items with push_back (or insert), you can choose its size from the start with arguments to the constructor, and you can resize it later with the resize method.
Creating a vector of vectors with your sizes with the constructor looks like this:
std::vector< std::vector<double> > matrix(size, std::vector<double>(sizeY));
This means: size instances of a std::vector<double>, each containing sizeY doubles (initialized to 0.0).
Sometimes you don't want to fill your stack and your memory requirement is large. Hence you may want to use vector> created dynamically especially while creating a table of a given row and col values.
Here is my take on this in C++11
int main() {
int row, col;
std::cin >> row >> col;
auto *arr = new std::vector<std::vector<int>*>(row);
for (int i=0; i<row; i++) {
auto *x = new std::vector<int>(col, 5);
(*arr)[i] = x;
}
for (int i=0; i<row; i++) {
for(int j=0; j<col; j++) {
std::cout << arr->at(i)->at(j) << " ";
}
std::cout << std::endl;
}
return 0;
}
#include < iostream >
#include < vector >
using namespace std;
int main(){
vector<int>*v = new vector<int>(); // for 1d vector just copy paste it
v->push_back(5);
v->push_back(10);
v->push_back(20);
v->push_back(25);
for(int i=0;i<v->size();i++){
cout<<v->at(i)<<" ";
}
cout<<endl;
delete v;
system("pause");
return 0;
}
If you don't need to resize the array sizes at run time, then you can just use standard arrays (allocated at runtime)!
However, if you do need to resize arrays at runtime, then you can use the following (revised) code:
#include <vector>
typedef std::vector< std::vector<double> > matrix;
//... various code and other stuff
std::vector<double> *name = new std::vector<double> (size);
matrix *name2 = new matrix(sizeX, std::vector<double>(sizeY));
In essence, all I've done is remove a single bracket (().