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);
Related
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;
}
I would like to return an array to a pointer, in a virtual function that is a member of a derived class of a template class. In details, my classes definition is:
Sampler.h
#ifndef SAMPLER_H
#define SAMPLER_H
template <class T>
class Sampler
{
public:
virtual T getnumber()=0;
virtual T* simulation(int n)=0;
};
class UniformSampler:public Sampler<double>
{
public:
virtual double getnumber();
virtual double* simulation(int n);
UniformSampler(double a=0.0, double b=1.0);
private:
double low_bound;
double up_bound;
};
#endif
The class Sampler is a template class in order to be able to derive an other sampler with vectors later. The implementation is:
Sampler.cpp
#include "Sampler.h"
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
//Uniform
UniformSampler::UniformSampler(double a, double b)
{
low_bound=a;
up_bound=b;
}
double UniformSampler::getnumber()
{
int myrand=rand();
while((myrand==0)||(myrand==RAND_MAX)){myrand = rand(); } //We want a number in (0, RAND_MAX).
double myuni = myrand/static_cast<double>(RAND_MAX); //Create a number in (0,1).
return low_bound + myuni*(up_bound-low_bound);
}
double* UniformSampler::simulation(int n){
double simulations[n];
for(int i=0; i<n; i++){
simulations[i] = this->getnumber();
}
return simulations;
}
My problem is that, when I try to call this program in the main(), it looks like the assignment of the pointer doesn't work. Here is my main.cpp:
#include <iostream>
#include <math.h>
#include <cstdlib>
#include <time.h>
using namespace std;
#include "Sampler.h"
int main(){
srand(time(0));
int n=10;
double *unif = new double[n];
UniformSampler uni;
unif = uni.simulation(n);
for ( int i = 0; i < n; i++ ) {
cout << "*(p + " << i << ") : ";
cout << *(unif + i) << endl;
}
delete[] unif;
return 0;
}
When I run it, it doesn't print any of the elements that unif points to. I don't understand what is wrong there.
UniformSampler::simulation is twice wrong:
double simulations[n]; uses VLA extension, so not C++ standard compliant.
you return pointer on local variable, so dangling pointer.
Solution: use std::vector instead.
#include <vector>
template <class T>
class Sampler
{
public:
virtual ~Sampler() = default;
virtual T getnumber() = 0;
virtual std::vector<T> simulation(int n) = 0;
};
class UniformSampler:public Sampler<double>
{
public:
explicit UniformSampler(double a=0.0, double b=1.0);
double getnumber() overrid;
std::vector<double> simulation(int n) override
{
std::vector<double> res(n);
for (auto& val : res){
res = getnumber();
}
return res;
}
private:
double low_bound;
double up_bound;
};
int main(){
srand(time(0));
constexpr int n = 10;
UniformSampler uni;
auto unif = uni.simulation(n);
for (int i = 0; i < n; i++ ) {
std::cout << "p[" << i << "]: " << unif[i] << endl;
}
}
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
In my program I want to pass a few variables into a function and have that function run a for loop to write the data to console.
This is my code:
void WriteValue(int[] arr)
{
for(auto c : arr)
std::cout<<arr<<std::endl;
}
int main()
{
int a = 0;
int b = 1;
int c = 3;
WriteValue(a,b,c);
return 0;
}
I know this would work in C# with params, but I don't have that option. How do I get this to run in C++?
Here's a very simple and flexible way:
#include <iostream>
template<typename T>
void WriteValue(const T& arr)
{
for(auto c : arr)
std::cout << c << std::endl;
}
int main()
{
int a = 0;
int b = 1;
int c = 3;
WriteValue(std::array<int, 3>{a,b,c});
// nicer C99 way: WriteValue((int[]){a,b,c});
return 0;
}
If you only want to be able to pass a list of ints (and it has to be a brace-separated list, not an existing array), you can instead do
#include <iostream>
#include <initializer_list>
void WriteValue(const std::initializer_list<int>& arr)
{
for(auto c : arr)
std::cout << c << std::endl;
}
int main()
{
int a = 0;
int b = 1;
int c = 3;
WriteValue({a,b,c});
return 0;
}
Unfortunately, VS2012 doesn't support this. You can upgrade to Visual 2013 (the Express Edition and Community Edition are both free), or you can use a helper variable:
#include <iostream>
template<typename T>
void WriteValue(const T& arr)
{
for(auto c : arr)
std::cout << c << std::endl;
}
int main()
{
int a = 0;
int b = 1;
int c = 3;
int args[] = { a, b, c };
WriteValue(args);
return 0;
}
Here I have a very simple program. My aim is to let b equal c, that is to copy all the content of c into b. But I don't know how. The getdata() function returns a pointer pointing to array of objects c, but how can it be used to put c into b?
#include<iostream>
#include<stdlib.h>
using namespace std;
class A
{
public:
A(int i,int j):length(i),high(j){}
int length,high;
};
class B
{
private:
A c[3] = {A(9,9),A(9,9),A(9,9)};
public:
A* getdata()
{
return c;
}
};
int main()
{
A b[3]={A(0,0),A(0,0),A(0,0)};
B *x = new B();
cout<< x->getdata() <<endl;
cout << b[1].length<<endl;
return 0;
}
In modern C++, make yourself a favor and use a convenient container class to store your arrays, like STL std::vector (instead of using raw C-like arrays).
Among other features, std::vector defines an overload of operator=(), which makes it possible to copy a source vector to a destination vector using a simple b=c; syntax.
#include <vector> // for STL vector
....
std::vector<A> v; // define a vector of A's
// use vector::push_back() method or .emplace_back()
// or brace init syntax to add content in vector...
std::vector<A> w = v; // duplicate v's content in w
That's a possible partial modification of your code, using std::vector (live here on codepad):
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A(int l, int h) : length(l), high(h) {}
int length, high;
};
class B
{
private:
vector<A> c;
public:
const vector<A>& getData() const
{
return c;
}
void setData(const vector<A>& sourceData)
{
c = sourceData;
}
};
int main()
{
vector<A> data;
for (int i = 0; i < 3; ++i) // fill with some test data...
data.push_back(A(i,i));
B b;
b.setData(data);
const vector<A>& x = b.getData();
for (size_t i = 0; i < x.size(); ++i) // feel free to use range-for with C++11 compilers
cout << "A(" << x[i].length << ", " << x[i].high << ")\n";
}
Instead of creating an array of A i.e. 'b' in main, create a pointer to A. And then initialize it by calling the getdata().
A *b;
B *x = new B();
b = x->getdata();
Here is an example
#include <iostream>
#include <algorithm>
class A
{
public:
A( int i, int j ) : length( i ), high( j ){}
int length, high;
};
class B
{
private:
A c[3] = {A(9,9),A(9,9),A(9,9)};
public:
A* getdata()
{
return c;
}
};
int main()
{
A b[3] = { A(0,0), A(0,0), A(0,0) };
B *x = new B();
A *c = x->getdata();
std::copy( c, c + 3, b );
for ( const A &a : b ) std::cout << a.length << '\t' << a.high << std::endl;
delete []x;
return 0;
}
The output is
9 9
9 9
9 9
Instead of standard algorithm std::copy you may use an ordinary loop. For example
for ( size_t i = 0; i < 3; i++ ) b[i] = c[i];