boost::flyweight doesn't work for class - c++

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:

Related

Working with std::unique_ptr and std::queue

Maybe it's my sinuses and that I fact that I just started learning about smart pointers today I'm trying to do the following:
Push to the queue
Get the element in the front
Pop the element (I think it will automatically deque once the address out of scope)
Here is the error
main.cpp:50:25: error: cannot convert ‘std::remove_reference&>::type’ {aka ‘std::unique_ptr’} to ‘std::unique_ptr*’ in assignment
50 | inputFrame = std::move(PacketQueue.front());
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
| |
| std::remove_reference<std::unique_ptr<MyObject::Packet>&>::type {aka std::unique_ptr<MyObject::Packet>}
Here is the code
#include <iostream>
#include <memory>
#include <queue>
using namespace std;
class MyObject
{
public:
struct Packet
{
uint8_t message;
uint8_t index;
};
void pushToQueue(void);
void FrontOfQueue(std::unique_ptr<Packet> *inputFrame);
private:
std::queue<std::unique_ptr<Packet>> PacketQueue;
};
void MyObject::pushToQueue(void)
{
Packet frame;
static int counter = 1;
frame.message = counter;
frame.index =counter;
counter++;
std::unique_ptr<Packet> passthru_ptr = std::make_unique<Packet>(std::move(frame));
PacketQueue.push(std::move(passthru_ptr));
cout<<"Pushed to queue\n" ;
}
void MyObject::FrontOfQueue(std::unique_ptr<Packet> *inputFrame)
{
inputFrame = std::move(PacketQueue.front());
}
int main()
{
cout<<"Hello World\n";
MyObject object;
object.pushToQueue();
object.pushToQueue();
{
// Scope
std::unique_ptr<MyObject::Packet> *frame;
object.FrontOfQueue(frame);
cout<< frame << endl;
}
{
// Scope
std::unique_ptr<MyObject::Packet> *frame2;
object.FrontOfQueue(frame2);
cout<< frame2 << endl;
}
return 0;
}
Link to the code (Online Compiler)
If I got your aim correctly, you definitely want
std::unique_ptr<MyObject::Packet> MyObject::FrontOfQueue()
{
auto rv = std::move(PacketQueue.front());
PacketQueue.pop();
return rv;
}
// ...
std::unique_ptr<MyObject::Packet> frame = object.FrontOfQueue();
Notice, no raw pointers are used.
I think it will automatically deque once the address out of scope.
This assumption is wrong. Nothing is dequeued until .pop() is called.
Here is my example with some extra logging to show whats going on.
includes an introduction of returning const references as well.
Live demo : https://onlinegdb.com/P2nFkdMy0
#include <iostream>
#include <memory>
#include <queue>
#include <string>
//-----------------------------------------------------------------------------
// do NOT use : using namespace std;
//-----------------------------------------------------------------------------
struct Packet
{
// moved to uint32_t for std::cout reasons.
// uint8_t is displayed as(special) characters
std::uint32_t index;
std::uint32_t message;
Packet() :
index{ next_index() },
message{ index }
{
std::cout << "created packet : " << index << "\n";
}
~Packet()
{
std::cout << "destroyed packet : " << index << "\n";
}
// small helper to not have to declare the static variable seperatly
static std::uint8_t next_index()
{
static int counter;
return counter++;
}
};
//-----------------------------------------------------------------------------
class MyObject
{
public:
void push_packet();
std::unique_ptr<Packet> pop_packet();
// this function returns a const reference (observation only)
// of the packet at the front of the queue
// while leaving the unique pointer on the queue (no moves needed
// packet will still be owned by the queue)
const Packet& front();
private:
std::queue<std::unique_ptr<Packet>> m_queue;
};
void MyObject::push_packet()
{
std::cout << "push_packet\n";
// push a packet
m_queue.push(std::make_unique<Packet>());
std::cout << "push_packet done...\n";
}
std::unique_ptr<Packet> MyObject::pop_packet()
{
std::unique_ptr<Packet> packet = std::move(m_queue.front());
m_queue.pop();
return packet;
}
const Packet& MyObject::front()
{
return *m_queue.front();
}
//-----------------------------------------------------------------------------
int main()
{
const std::size_t n_packets = 3ul;
MyObject object;
for (std::size_t n = 0; n < n_packets; ++n)
{
std::cout << "pushing packet\n";
object.push_packet();
}
for (std::size_t n = 0; n < n_packets; ++n)
{
std::cout << "packet at front : ";
std::cout << object.front().index << "\n";
std::cout << "popping front\n";
auto packet_ptr = object.pop_packet();
std::cout << "popped packet : " << packet_ptr->index << "\n";
}
return 0;
}

How to pass parameters in an objects of array? in c++

class A
{
int id;
public:
A (int i) { id = i; }
void show() { cout << id << endl; }
};
int main()
{
A a[2];
a[0].show();
a[1].show();
return 0;
}
I get an error since there is no default constructor.However thats not my question.Is there a way that ı can send parameters when defining
A a[2];
A good practice is to declare your constructor explicit (unless it defines a conversion), especially if you have only one parameter. Than, you can create new objects and add them to your array, like this :
#include <iostream>
#include <string>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
A first(3);
A second(4);
A a[2] = {first, second};
a[0].show();
a[1].show();
return 0;
}
However, a better way is to use vectors (say in a week you want 4 objects in your array, or n object according to an input). You can do it like this:
#include <iostream>
#include <string>
#include <vector>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
std::vector<A> a;
int n = 0;
std::cin >> n;
for (int i = 0; i < n; i++) {
A temp(i); // or any other number you want your objects to initiate them.
a.push_back(temp);
a[i].show();
}
return 0;
}

In C/C++, I am trying to call different functions (explained in description) in a for loop without if-else ladder

I have some APIs defined like following prototype.
void foo_network_call_1();
void foo_network_call_2();
void foo_network_call_3();
void foo_network_call_4();
and
void foo_parse_data_1();
void foo_parse_data_2();
void foo_parse_data_3();
void foo_parse_data_4();
I can make 4 calls to each type of API to get the work done. That code will not be clean etc.
I am looking for a way to call above APIs in a loop, e.g.for loop.
something like:
for (int i=1; i<5; ++i) {
foo_network_call_##i();
foo_parse_data_##i();
}
##
are just representing that I am appending i in the call. I am not aware of any calling mechanism in C/C++ which can do this.
Thank you your help.
Using an array of function pointers seems like the obvious thing to do.
typedef void (*network_func)();
typedef void (*parse_func)();
network_func network_functions[4] = { foo_network_call_1, ... };
parse_func parse_functions[4] = { foo_parse_data_1, ... };
for (int i = 0; i < 4; ++i)
{
(network_functions[i])();
(parse_functions[i])();
}
#include <iostream>
#include <vector>
using namespace std;
int main()
{
cout << "Hello World!" << endl;
auto foo_network_call_0 = [](){
//do something...
};
auto foo_network_call_1 = [](){
//do something...
};
auto foo_network_call_2 = [](){
//do something...
};
auto foo_network_call_3 = [](){
//do something...
};
auto foo_parse_data_0 = [](){
//do something...
};
auto foo_parse_data_1 = [](){
//do something...
};
auto foo_parse_data_2 = [](){
//do something...
};
auto foo_parse_data_3 = [](){
//do something...
};
std::vector<void(*)()> ary_call;
ary_call.push_back( foo_network_call_0 );
ary_call.push_back( foo_network_call_1 );
ary_call.push_back( foo_network_call_2 );
ary_call.push_back( foo_network_call_3 );
std::vector<void(*)()> ary_data;
ary_data.push_back( foo_parse_data_0 );
ary_data.push_back( foo_parse_data_1 );
ary_data.push_back( foo_parse_data_2 );
ary_data.push_back( foo_parse_data_3 );
for ( auto i = 0; i < 4; ++i ) {
ary_call[i]();
ary_data[i]();
}
return 0;
}
If it is just a static list of functions, put them into one function then call that.
Like:
void foo_network() {
void foo_network_call_1();
void foo_network_call_2();
void foo_network_call_3();
void foo_network_call_4();
}
two answer above is correct
the only way is function pointer
i usually write this model for my codes
typedef void (*NetworkFunc)(void);
typedef void (*ParseFunc)(void);
const NetworkFunc NetworkFunctions[] = {
network_func_1,
network_func_2,
...
};
const NetworkFunctions_Length = sizeof(NetworkFunctions) / sizeof(NetworkFunctions[0]);
const ParseFunc ParseFunctions[] = {
parse_func_1,
parse_func_2,
...
};
const ParseFunctions_Length = sizeof(ParseFunctions) / sizeof(ParseFunctions[0]);
now you can use it like this
for (i =0; i < NetworkFunctions_Length; i++) {
NetworkFunctions[i]();
}
for (i =0; i < ParseFunctions_Length; i++) {
ParseFunctions[i]();
}
Edit:
this is alternative c++ example
#include <iostream>
#include <functional>
using namespace std;
typedef function<void(void)> PrintFunc;
void Print_A(void);
void Print_B(void);
void Print_C(void);
const PrintFunc PrintFunctions[] = {
Print_A,
Print_B,
Print_C,
};
const int PrintFunctions_Length = sizeof(PrintFunctions) / sizeof(PrintFunctions[0]);
int main(void) {
for (int i = 0; i < PrintFunctions_Length; i++) {
PrintFunctions[i]();
}
}
void Print_A(void) {
cout << "A\n";
}
void Print_B(void) {
cout << "B\n";
}
void Print_C(void) {
cout << "C\n";
}
you can try to use an array of function pointers and every index will be a different function, that way the i indexing will work.
void (*network_call_arr[])() = {foo_network_call_1, foo_network_call_2, foo_network_call_3, foo_network_call_4};
void (*parse_data_arr[]() = {foo_parse_data_1, foo_parse_data_2, foo_parse_data_3, foo_parse_data_4};
and just call an index to a pointer from the for loop.
for (int i=0; i<4; ++i)
{
network_call_arr[i]();
parse_data_arr[i]();
}
You could also use a switch, which under optimization will probably compile to a jump table.
for (int i=1; i<5; ++i)
{ switch( i)
{ case 1:
foo_network_call_1();
foo_parse_data_1();
break;
case 2:
foo_network_call_2();
foo_parse_data_2();
break;
// etc
}
}
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
void foo_network_call_1(int data) {
cout <<"foo_network_call_1"<<endl;
}
void foo_network_call_2(int data) {
cout <<"foo_network_call_2"<<endl;
}
void foo_network_call_3(int data) {
cout <<"foo_network_call_3"<<endl;
}
void foo_network_call_4(int data) {
cout <<"foo_network_call_4"<<endl;
}
void foo_parse_data_1(string data) {
cout <<"foo_parse_data_1"<<endl;
}
void foo_parse_data_2(string data) {
cout <<"foo_parse_data_2"<<endl;
}
void foo_parse_data_3(string data) {
cout <<"foo_parse_data_3"<<endl;
}
void foo_parse_data_4(string data) {
cout <<"foo_parse_data_4"<<endl;
}
typedef std::function<void(int)> NewWorkFunc;
typedef std::function<void(string)> ParseDatFunc;
int main(int argc, char *argv[])
{
std::vector<NewWorkFunc> arrNetworkCalls;
std::vector<ParseDatFunc> arrParsedataCalls;
arrNetworkCalls.push_back(foo_network_call_1);
arrNetworkCalls.push_back(foo_network_call_2);
arrNetworkCalls.push_back(foo_network_call_3);
arrNetworkCalls.push_back(foo_network_call_4);
arrParsedataCalls.push_back(foo_parse_data_1);
arrParsedataCalls.push_back(foo_parse_data_2);
arrParsedataCalls.push_back(foo_parse_data_3);
arrParsedataCalls.push_back(foo_parse_data_4);
for(int i=0; i<4; ++i) {
arrNetworkCalls[i](i);
arrParsedataCalls[i](std::to_string(i));
}
return 0;
}

Problem with counting dynamic allocation. C++ [closed]

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

Is this a good way to store, iterate and delete pointers in an std::vector?

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
using namespace std;
struct delete_ptr
{
template<typename T>
void operator()(T*& t)
{
delete t;
t = 0;
}
};
struct is_null_ptr
{
template<typename T>
bool operator()(T*& t)
{
return t == 0;
}
};
struct A
{
static void removeDead(A*& a)
{
if(a and a->dead)
delete_ptr()(a);
}
static void killSome(A* a)
{
if(a and a->isDead() == false and rand()%100 == 0)
{
static int counter = 0;
cout << "Kill___" << ++counter << endl;
a->kill();
}
}
static void reviveSome(A* a)
{
if(a and a->isDead() and rand()%3 == 0)
{
static int counter = 0;
cout << "Revive___" << ++counter << endl;
a->revive();
}
}
A():dead(false)
{
}
virtual ~A()
{
static int counter = 0;
cout << "Dtor___" << ++counter << endl;
}
bool isDead(){return dead;}
void kill(){dead = true;}
void revive(){dead = false;}
bool dead;
};
int main()
{
srand(time(0));
vector<A*> as;
for(int i = 0; i < 200; ++i)
{
A* a = new A;
as.push_back(a);
}
for_each(as.begin(),as.end(),A::killSome);
for_each(as.begin(),as.end(),A::reviveSome);
for_each(as.begin(),as.end(),A::removeDead);
as.erase( std::remove_if(as.begin(),as.end(),is_null_ptr()),as.end());
cout << as.size() << endl;
for_each(as.begin(),as.end(),delete_ptr());
as.clear();
return 0;
}
It allocates them, and prints the right output but I'm not sure this is the right thing I'm doing. I was just trying to use pointers in a vector and delete them when a certain condition happens, without using boost or c++11.
So what do you think about it?
Since the only smart pointer present in the current STL (auto_ptr) cannot be used in containers, I would say your way is a good one under the given conditions.
You could think about implementing your own unique_ptr or shared_ptr however.
PS: There are many reasons to use pointers instead of the actual objects in a container, one is polymorphism. Another one is that the actual objects are already stored somewhere else (think of an index structure to already stored objects).