Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Hey I have written code and I don't know why it is not working, it suppose to count number of memory reservations but I have done something wrong (I mean no of memory allocations is equal to 0 in both counters) and I can't spot the problem, I will appreciate any help. First post here so please be patient. :D
#include <iostream>
#include <vector>
using std::cout; using std::endl;
struct A
{
int a;
static int nr;
void * operator new[](std::size_t n) {++nr; return ::new char[n]; }
};
struct B
{
double b;
static int nr;
void * operator new[](std::size_t n) {++nr; return ::new char[n]; }
};
int A::nr = 0, B::nr = 0;
int main()
{
std::vector<A> vecA;
std::vector<B> vecB;
for (int i{}; i < 1000; i++)
{
vecA.push_back(A());
vecB.push_back(B());
}
cout << "Size of vecA: " << vecA.size() * sizeof(A) << ", number of times that memory was allocated: " << A::nr << endl;
cout << "Size of vecB: " << vecB.size() * sizeof(B) << ", number of times that memory was allocated: " << B::nr << endl;
return 0;
}
To count the number of memory reallocation I only see creation of own allocator class. Something like:
template <typename T>
class countingAllocator : public std::allocator<T>
{
public:
template<typename _Tp1>
struct rebind
{
typedef countingAllocator<_Tp1> other;
};
T* allocate(size_t n, const void *hint = 0)
{
T::nr++;
return std::allocator<T>::allocate(n, hint);
}
countingAllocator() : std::allocator<T>()
{ }
countingAllocator(const countingAllocator &a) : std::allocator<T>(a)
{ }
template <class U>
countingAllocator(const countingAllocator<U> &a) : std::allocator<T>(a)
{ }
~countingAllocator()
{ }
};
// Fix for VS Debug build Don`t need for Release
template <>
class countingAllocator<std::_Container_proxy> : public
std::allocator<std::_Container_proxy>
{
public:
template <class U>
countingAllocator(const countingAllocator<U> &a) :
std::allocator<std::_Container_proxy>(a)
{ }
};
std::vector<A, countingAllocator<A>> vecA;
std::vector<B, countingAllocator<B>> vecB;
for (int i{}; i < 1000; i++)
{
vecA.push_back(A());
vecB.push_back(B());
}
Output:
Size of vecA: 4000, number of times that memory was allocated: 18
Size of vecB: 8000, number of times that memory was allocated: 18
You could try this:
#include <vector>
#include <iostream>
struct A
{
int a;
static int nr;
};
struct B
{
double b;
static int nr;
};
int A::nr = 0, B::nr = 0;
int main ()
{
std::vector<A> vecA;
std::vector<B> vecB;
size_t A_capacity = 0, B_capacity = 0;
for (int i{}; i < 1000; i++)
{
vecA.push_back(A());
if (vecA.capacity () != A_capacity)
{
++A::nr;
A_capacity = vecA.capacity ();
}
vecB.push_back(B());
if (vecB.capacity () != B_capacity)
{
++B::nr;
B_capacity = vecB.capacity ();
}
}
std::cout << "A: " << A::nr << ", B: " << B::nr;
}
Output:
A: 11, B: 11
Live demo
Related
This question already has an answer here:
Initializing an std::array of non-default-constructible elements?
(1 answer)
Closed 2 years ago.
I want to initialize a array of 1 million objects on stack, I need to write one million &i in the following code.
Is there any other good way.
#include <iostream>
class A{
public:
A(int* p)
: p_(p){
std::cout << "A" << std::endl;
}
private:
int *p_;
};
int main(){
int i;
A a[3] = {&i, &i, &i};
}
#include <iostream>
#include <type_traits>
class A{
public:
A(int* p)
: p_(p){
std::cout << "A" << std::endl;
}
private:
int *p_;
};
int main(){
using elemType = std::aligned_storage<sizeof(A), alignof(A)>::type;
const size_t count = 1000000;
int i;
elemType a[count];
for(int idx = 0; idx < count: ++idx) {
new (&a[idx]) A(&i);
}
...
for(int idx = 0; idx < count: ++idx) {
reinterpret_cast<A&>(a[idx]).~A();
}
return 0;
}
C++ new operator can be used to call constructor on a preallocated memory:
#include <iostream>
#include <cstddef>
#include <cstdint>
class A{
public:
A(int* p)
: p_(p){
std::cout << "A" << std::endl;
}
private:
int *p_;
};
int main(){
int i;
uint8_t buf[1000000 * sizeof(A)];
A* pa = reinterpret_cast<A*>(buf);
for (size_t n = 0; n < 1000000; n++) {
new (&pa[n]) A(&i);
}
return 0;
}
You could use std::vector and initialize is with a million elements
std::vector<A> a(1000000, &i);
I want to implement a class that uses N-dimensional vectors (from the mathematical point of view). I'm using Vec objects from the opencv library, and their signature looks like this: Vec<typename _Tp, int cn> where cn is the number of elements inside that vector. I must provide a constant for the cn parameter.
I want my class to look something like this:
class MyClass
{
private:
Vec<float, dim> m_center;
vector<Vec<float, dim>> m_points;
// ...
}
and I want to be able to initialize dim dinamically, that is create a MyClass object that has its dim set to whatever number I want. How can I correctly approach this problem in C++?
template <typename T, int N=9>
class Vec
{
public:
Vec()
{
//auto deleter = [](T* t) { delete[] t; };
//unique_ptr <T, decltype(deleter)> test(new T[N], deleter); //customized deleter omitted
t = new T[N];
}
Vec(const Vec &v)
{
sz = v.sz;
t = new T[sz];
}
string getType()
{
return typeid(T).name();
}
int getSize()
{
return sz;
}
~Vec()
{
delete [] t;
}
private:
T *t;
int sz = N;
};
template<int dim = 1>
class MyClass
{
public:
MyClass()
{
m_points.resize(2);
}
Vec<float, dim> getCenter()
{
return m_center;
}
vector<Vec<float, dim>> getPoints()
{
return m_points;
}
private:
Vec<float, dim> m_center;
vector<Vec<float, dim>> m_points;
};
Test code:
int main()
{
MyClass<10> my;
cout << "center size = " << my.getCenter().getSize() << endl;
cout << "center type =" << my.getCenter().getType().c_str() << endl;
cout << "points size" << my.getPoints().size() << endl;
cout << "first point size = " << my.getPoints()[0].getSize() << endl;
cout << "first point type =" << my.getPoints()[0].getType().c_str() << endl;
std::cout << "Hello World!\n";
}
Output:
center size = 10
center type =float
points size2
first point size = 10
first point type =float
Hello World!
compile time value cannot be runtime value.
If range of value is small enough, you might generate all possible values and dispatch afterward.
It seems you just have to handle 1, 2 and 3, so something like:
template <std::size_t dim>
class MyClass
{
public:
void DoFullJob();
private:
Vec<float, dim> m_center;
vector<Vec<float, dim>> m_points;
// ...
};
int main()
{
int i = 0;
std::cin >> i;
switch (i) {
case 1: { MyClass<1>{}.DoFullJob(); break; }
case 2: { MyClass<2>{}.DoFullJob(); break; }
case 3: { MyClass<3>{}.DoFullJob(); break; }
default: // Error message, or nothing...
}
}
For bigger ranges, switch case might be replaced by array of functors generated by std::index_sequence.
first i used flyweight for string which works fine, but when i use flyweight for a struct. it doesn't work.
the first test case for string is:
static void testflyweightString()
{
char tmp[0];
vector<boost::flyweight<string>> boost_v;
for(int i=0;i<10000000;i++)
{
sprintf(tmp,"zws_%d",i/1000);
boost_v.pushback(boost::flyweight<string>(tmp));
}
return;
}
then i defined a struct A, some properties in A i used flyweight.
testcase2 is as below:
static void testflyweightA()
{
vector<A> boost_v;
for(int i=0;i<10000000;i++)
{
A a();//here new some A;
boost_v.pushback(a);
}
return;
}
but it doesn't have any change for memory used whether i used flyweight in A or not.
First off:
A a();//here new some A;
This is: Most vexing parse: why doesn't A a(()); work?
I prepared this test program:
Live On Coliru
#include <boost/flyweight.hpp>
#include <vector>
#include <iostream>
static void testflyweightString() {
std::cout << __FUNCTION__ << "\n";
std::vector<boost::flyweight<std::string> > boost_v;
for (int i = 0; i < 10000000; i++) {
boost_v.emplace_back("zws_" + std::to_string(i/1000));
}
}
struct A {
boost::flyweight<std::string> s;
A(std::string const& s) : s(s) { }
};
static void testflyweightA() {
std::cout << __FUNCTION__ << "\n";
std::vector<A> boost_v;
for (int i = 0; i < 10000000; i++) {
boost_v.push_back("zws_" + std::to_string(i/1000));
}
}
int main() {
testflyweightString();
testflyweightA();
std::cout << "Done\n";
}
Its memory usage looked ok using valgrind --tool=massif:
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
My first question is: I am having a lot of trouble figuring out why the Example class is being constructed greater than the others. Below is a short app using a Template counter to track how many times the constructor/destructor/copy constructor is called for each class. There are a total of three classes: Example, Deep, Child. Each has a copy constructor... ugh.
Also, my second question, is what would be the correct way to define the copy constructor for the Child class?
In the printStatus(), it displays:
COUNTERS::NEW_COUNTER = 60
COUNTERS::DELETE_COUNTER = 50
COUNTERS::CONSTRUCTOR_COUNTER = 90
COUNTERS::DESTRUCTOR_COUNTER = 80
Example count = 10
Deep count = 0
Child count = 0
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class COUNTERS
{
public:
static int NEW_COUNTER;
static int DELETE_COUNTER;
static int CONSTRUCTOR_COUNTER;
static int DESTRUCTOR_COUNTER;
};
int COUNTERS::NEW_COUNTER = 0;
int COUNTERS::DELETE_COUNTER = 0;
int COUNTERS::CONSTRUCTOR_COUNTER = 0;
int COUNTERS::DESTRUCTOR_COUNTER = 0;
/* template used for counting constructors/destructors to debug memory leaks */
template <typename T>
class Countable
{
static unsigned cs_count_;
public:
Countable() { ++cs_count_; }
Countable( Countable const& ) { ++cs_count_; }
virtual ~Countable() { --cs_count_;}
static unsigned count() { return cs_count_; }
};
template <typename T>
unsigned Countable<T>::cs_count_ = 0;
class Example : public Countable<Example>
{
public:
string a;
int b;
Example() {
COUNTERS::CONSTRUCTOR_COUNTER++;
a = "exampleString";
b = 5;
}
virtual ~Example() {
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Example(const Example& e) {
COUNTERS::CONSTRUCTOR_COUNTER++;
this->a = e.a;
this->b = e.b;
}
};
class Deep : public Countable<Deep>
{
public:
int a;
string b;
Example* e;
Deep()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
a = 3;
b = "deepString";
e = new Example();
COUNTERS::NEW_COUNTER++;
}
virtual ~Deep() {
if(e != NULL) {
delete e;
COUNTERS::DELETE_COUNTER++;
}
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Deep(const Deep& x)
{
COUNTERS::CONSTRUCTOR_COUNTER++;
this->a = x.a;
this->b = x.b;
this->e = new Example();
COUNTERS::NEW_COUNTER++;
this->e->a = x.e->a;
this->e->b = x.e->b;
};
};
class Child : public Countable<Child>
{
public:
Deep d;
string name;
int age;
Example* e;
vector<Example> list;
vector<Deep> deep_list;
void init()
{
Deep* var = new Deep(); COUNTERS::NEW_COUNTER++;
deep_list.push_back(*var);
delete var; COUNTERS::DELETE_COUNTER++;
}
Child() {
COUNTERS::CONSTRUCTOR_COUNTER++;
name = "a";
age = 10;
d.a = 1;
d.b = "deep";
d.e = NULL;
e = new Example();
COUNTERS::NEW_COUNTER++;
list.push_back(*e);
init();
}
virtual ~Child() {
COUNTERS::DESTRUCTOR_COUNTER++;
if(e != NULL) {
delete e;
COUNTERS::DELETE_COUNTER++;
}
}
// copy constructor
Child(const Child& c)
{
}
};
void myChildFunction(){
Child* c = new Child();
COUNTERS::NEW_COUNTER++;
delete c;
COUNTERS::DELETE_COUNTER++;
}
void printStatus(){
cout << "COUNTERS::NEW_COUNTER = " << COUNTERS::NEW_COUNTER << endl;
cout << "COUNTERS::DELETE_COUNTER = " << COUNTERS::DELETE_COUNTER << endl;
cout << "COUNTERS::CONSTRUCTOR_COUNTER = " << COUNTERS::CONSTRUCTOR_COUNTER << endl;
cout << "COUNTERS::DESTRUCTOR_COUNTER = " << COUNTERS::DESTRUCTOR_COUNTER << endl;
cout << "Example count = " << Example::count() << endl;
cout << "Deep count = " << Deep::count() << endl;
cout << "Child count = " << Child::count() << endl;
}
int main()
{
for(unsigned int i=0 ; i < 10; i++)
myChildFunction();
printStatus();
return 0;
}
You are missing out on deleting some Example objects because of this line:
d.e = NULL;
in Child::Child().
You are allocating memory for e in the constructor of Deep. After executing the above line, that memory is leaked.
You can resolve that problem by:
Removing that line (or commenting it out),
Deleting d.e before making it NULL, or
Doing something else that prevents the memory leak.
Update, in response to comment
Copy constructor for Child:
Child(const Child& c) : d(c.d),
name(c.name),
age(c.age),
e(new Example(*c.e)),
list(c.list),
deep_list(c.deep_list)
{
COUNTERS::DESTRUCTOR_COUNTER++; // This is for Child
COUNTERS::NEW_COUNTER++; // This is for new Example
}
I removed all information that cluttered your code.
When using templates, constructors and copy constructors NEED the following: Example < eltType >(void);
in the class definition. All objects that inherit from Countables are known as derived classes. They also may call a derived class a child, and the class in which it is derived from is called the parent. I added the COPY_CONSTRUCTOR_COUNT to add clarification to the data which is being presented on the console/command prompt. Usually when trying to preform a task, large or small, doing it incrementally and by providing methods, for each task, saves you time and a headache. I removed the new_count and delete_count from the equation, because I felt that it was not needed.
You will notice that I added : Countable( * ((Countable < eltType > *)&e))
This is a requirement when designing a program that involves inheritance, which introduces the
topic of Polymorphism :D
What that bit of code does is that it gets a pointer of a Countable, which will point to the address of object e, which then allows access to all super classes of this class, but not including e's class.
NOTE: Since e is a derived class of Countable, this is valid statement.
For you second question, all of your data members are public, you can use an iterator to copy your data stored in you vectors.
As a concern from one programmer to another, I hope your code in practice is well documented, and all methods declared in your class are defined in a .cpp file.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class COUNTERS
{
public:
static int NEW_COUNTER;
static int DELETE_COUNTER;
static int CONSTRUCTOR_COUNTER;
static int DESTRUCTOR_COUNTER;
static int COPY_CONSTRUCTOR_COUNTER;
};
int COUNTERS::NEW_COUNTER = 0;
int COUNTERS::DELETE_COUNTER = 0;
int COUNTERS::CONSTRUCTOR_COUNTER = 0;
int COUNTERS::DESTRUCTOR_COUNTER = 0;
int COUNTERS::COPY_CONSTRUCTOR_COUNTER = 0;
/* template used for counting constructors/destructors to debug memory leaks */
template <typename T>
class Countable
{
public:
Countable<T>()
{
incrementObjectCount();
};
Countable<T>(Countable const&)
{
incrementObjectCount();
};
virtual ~Countable()
{
decrementObjectCount();
};
static unsigned count()
{
return cs_count_;
};
protected:
static unsigned cs_count_;
////////////////////////////////////ADDED////////////////////////////////////
protected:
void incrementObjectCount(void){ ++cs_count_; };
void decrementObjectCount(void){ --cs_count_; };
void incrementDeconstructorCounter(void){ ++COUNTERS::DESTRUCTOR_COUNTER; };
/////////////////////////////////////ADDED////////////////////////////////////
};
template <typename T>
unsigned Countable<T>::cs_count_ = 0;
class Example : public Countable<Example>
{
public:
Example() : Countable<Example>()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
}
virtual ~Example()
{
incrementDeconstructorCounter();
}
// copy constructor
Example(const Example& e) : Countable<Example>(*((Countable<Example>*)&e))
{
// COUNTERS::CONSTRUCTOR_COUNTER++; This is copy constructor, you addmitted this from "Child" class CCstr
++COUNTERS::COPY_CONSTRUCTOR_COUNTER; // For even more information added this
}
};
class Deep : public Countable<Deep>
{
public:
Deep() : Countable<Deep>()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
}
virtual ~Deep()
{
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Deep(const Deep& x) : Countable<Deep>(*((Countable<Deep>*)&x))
{
//COUNTERS::CONSTRUCTOR_COUNTER++;
++COUNTERS::COPY_CONSTRUCTOR_COUNTER; // For even more information added this
};
};
class Child : public Countable<Child>
{
public:
vector<Example> list;
vector<Deep> deep_list;
void init()
{
deep_list.push_back(Deep());
list.push_back(Example());
}
Child() : Countable<Child>()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
init();
}
virtual ~Child()
{
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Child(const Child& c) : Countable<Child>(*((Countable<Child>*)&c))
{
++COUNTERS::COPY_CONSTRUCTOR_COUNTER; // For even more information added this
}
};
void myChildFunction(){
Child* c = new Child();
//COUNTERS::NEW_COUNTER++;not needed
delete c;
//COUNTERS::DELETE_COUNTER++; not need
}
void printStatus(){
cout << "COUNTERS::NEW_COUNTER = " << COUNTERS::NEW_COUNTER << endl;
cout << "COUNTERS::DELETE_COUNTER = " << COUNTERS::DELETE_COUNTER << endl;
cout << "COUNTERS::CONSTRUCTOR_COUNTER = " << COUNTERS::CONSTRUCTOR_COUNTER << endl;
cout << "COUNTERS::DESTRUCTOR_COUNTER = " << COUNTERS::DESTRUCTOR_COUNTER << endl;
cout << "COUNTERS::COPY_CONSTRUCTOR_COUNTER = " << COUNTERS::COPY_CONSTRUCTOR_COUNTER << endl;
cout << "Example count = " << Example::count() << endl;
cout << "Deep count = " << Deep::count() << endl;
cout << "Child count = " << Child::count() << endl;
}
int main()
{
for (unsigned int i = 0; i < 10; i++)
myChildFunction();
printStatus();
system("pause");
return 0;
}
I would like to implement a Base class with attributes of a size I already know at compile-time. So my idea was to use a template for this Base class. The following code compiles and runs fine under VC++9.0.
Class definition in the .h file
template<int N> class BaseClass
{
int* idx;
int* incr;
int* limit;
public:
BaseClass(void);
~BaseClass(void);
void LoopMethod(void);
};
Implementation of the class methods in the .cpp file
#include "BaseClass.h"
#include<iostream>
using namespace std;
// instantiation
template class BaseClass<2>;
template<int N> BaseClass<N>::BaseClass(void)
{
idx = new int [N];
incr= new int [N];
limit = new int[N];
for(int m = 0; m < N; m++)
{
idx[m] = 0;
incr[m] = 1;
limit[m] = 2;
}
}
template<int N> BaseClass<N>::~BaseClass(void)
{
}
template<int N> void BaseClass<N>::LoopMethod( )
{
for( idx[N-1]; idx[N-1] < limit[N-1]; idx[N-1] += incr[N-1] )
{
cout << "LoopMethod Nr " << N-1 << " is called." << endl;
}
}
Implementation of the main-function:
#include<cstdlib>
#include "BaseClass.h"
using namespace std;
int main()
{
BaseClass<2> baseObj;
baseObj.LoopMethod();
system("PAUSE");
return 0;
}
Now I want to nest the for-loops from the LoopMethod times the size of the class attributes. I.e. the compiler should generate a code I would write by Hand as
template<int N> void BaseClass<N>::LoopMethod( )
{
for( idx[0]; idx[0] < limit[0]; idx[0] += incr[0] )
{
for( idx[1]; idx[1] < limit[1]; idx[1] += incr[1] )
{
cout << "LoopMethod Nr " << 1 << " is called." << endl;
}
cout << "LoopMethod Nr " << 0 << " is called." << endl;
}
}
Anyway, I can prompt the compiler to do this, if I do not declare the BaseClass to be a template class. The code for this would then look like:
class BaseClass
{
int* idx;
int* incr;
int* limit;
public:
BaseClass(void);
~BaseClass(void);
template<int M> void LoopMethod(void);
};
Implementation of the class methods in the .cpp file
#include "BaseClass.h"
#include<iostream>
using namespace std;
template void BaseClass::LoopMethod<1>();
BaseClass::BaseClass(void)
{
idx = new int [2];
incr= new int [2];
limit = new int[2];
for(int m = 0; m < 2; m++)
{
idx[m] = 0;
incr[m] = 1;
limit[m] = 2;
}
}
BaseClass::~BaseClass(void)
{
}
template<int M> void BaseClass::LoopMethod( )
{
for( idx[M]; idx[M] < limit[M]; idx[M] += incr[M] )
{
cout << "LoopMethod Nr " << M-1 << " is called." << endl;
LoopMethod<M-1>();
}
}
template<> void BaseClass::LoopMethod<0>(void)
{
idx[0] = 0;
for( idx[0]; idx[0] < limit[0]; idx[0] += incr[0] )
{
// do something
cout << "Now the inner loop is executed" << endl;
}
}
Implementation of the main-function:
#include<cstdlib>
#include "BaseClass.h"
using namespace std;
int main()
{
BaseClass baseObj;
baseObj.LoopMethod<1>();
system("PAUSE");
return 0;
}
But the solution I am searching for is to have a template class with a template method “LoopMethod” owing its own template parameter which tells the compiler how many times to nest the for-Loop. I have tried various possibilities but without success. Does anybody have a suggestion or even know a solution for this template problem?
Thanks in advance for your help,
Markus.
There are a lot of issues with your template:
What exactly is the purpose of the whole thing?
Why are you initialising the pointers with new? You know the size at compile time so why not just make them arrays?
You are not deleting the memory you are allocating
Exception safety if new fails for one of the later arrays
Implementation probably should be in the header file unless it is used for very few values of N which you instantiate
Better to use classes that exist that do this kind of thing, eg boost::array
Refactor out various sections of it.
But the solution I am searching for is
to have a template class with a
template method “LoopMethod” owing its
own template parameter which tells the
compiler how many times to nest the
for-Loop
Is that what you are asking:
template<int N>
struct X
{
template<int M>
void loop();
};
template<int N>
template<int M>
void X<N>::loop<M>()
{
}