This small example is giving the error message
Error C2440 '=': cannot convert from '_Ux (*const )' to 'int *' Templ 1266
Error C3692 non-scalar type 'int []' cannot be used in a pseudo-destructor expression
What is _Ux(*const)?
This is the program:
#include <memory>
int main()
{
shared_ptr<int[]> as = make_shared<int[]>(10);
for (int i = 0; i < 10; i++) {
as[i] = i + 100;
}
}
The code as shown does not compile, because shared_ptr and make_shared() are in the std namespace, but there is no using namespace std; statement, or at least using std::shared_ptr; and using std::make_shared; statements.
However, fixing that, make sure you are compiling this code for C++20, as std::make_shared() does not support the creation of arrays in earlier versions, which can lead to the error you are seeing.
In C++17, you will have to construct the array manually instead, but std::shared_ptr will free the array correctly, eg:
std::shared_ptr<int[]> as( new int[10] );
Live Demo
But, std::shared_ptr does not support arrays at all in C++11 and C++14, so you will have to use a custom deleter to free the array properly, and use std::shared_ptr::get() instead of std::shared_ptr::operator[] to access the array elements, eg:
#include <memory>
int main()
{
std::shared_ptr<int> as( new int[10], [](int *p) { delete[] p; } );
for (int i = 0; i < 10; i++) {
as.get()[i] = i + 100;
}
}
For dynamic arrays, you should consider using std::vector instead, eg:
#include <vector>
int main()
{
std::vector<int> as(10);
for (int i = 0; i < 10; i++) {
as[i] = i + 100;
}
}
Related
I am using the Eigen linear algebra library. I struggling trying to allocate Eigen Vectors in the constructor in a class, and then calling the elements of those vectors.
For example,
#include <Eigen/Dense>
using Eigen::VectorXd;
#include <memory>
using std::unique_ptr;
class Cl
{
public:
unique_ptr<VectorXd> v;
Cl(const int n);
~Cl(void);
}
Cl::Cl(const int n)
{
auto v= unique_ptr<VectorXd>(new VectorXd(n));
}
Cl::~Cl(void)
{
v= nullptr;
}
main(void)
{
Cl cl(10);
/* call an element of v how? */
}
For example, using "cl.v(2)" gives me the compiler error (I am using clang++)
error: type 'unique_ptr<VectorXd>' (aka 'unique_ptr<Matrix<double, Dynamic, 1> >') does
not provide a call operator
while using "cl.(*v)(2)" gives me
error: expected unqualified-id
cout << cl.(*v)(2) << endl;
I am new to c++, so I may be missing something very basic here.
Why are you trying to dynamically allocate the Eigen::VectorXd v; itself? Unless you would like to extend the lifetime of v beyond the lifetime of cl (in which case you would indeed have to do so), I would recommend to follow the following simple example:
#include <Eigen/Dense>
using Eigen::VectorXd;
class Cl
{
public:
VectorXd v;
Cl(int n) : v(n) {}
~Cl() {}
}
int main()
{
Cl cl(10);
for (int i=0; i<10; ++i)
cl.v(i) = i;
}
I believe in addition to the answers already regarding std::vector you are also misusing your 'unique_ptr', if indeed you actually require the use of one (reference ggael answer). Please see below example on the use of unique_ptr:
#include <iostream>
#include <memory>
#include <vector>
class Cl {
public:
std::unique_ptr<std::vector<int>> v;
Cl(const int size, int default_values);
~Cl(void);
int Size();
};
Cl::Cl(const int size, int default_values = 0) {
v.reset(new std::vector<int>(size, default_values));
}
Cl::~Cl(void) {
// do not require to reset/destroy an auto_ptr so this can be ommitted
}
int Cl::Size() {
return v->size();
}
int main(int argc, char* argv[]) {
Cl blob(10);
int size = blob.Size();
std::cout << size << std::endl;
}
In your provided code you're declaring a new auto in the constructor rather than using the variable you've defined in your Public class definition. I've included a 'Size' method so you can see the scope extends beyond the constructor.
I am trying to loop through a struct array and initialize its member "history", an int array, to 0 (Undoubtedly, you'll have a better suggestion than the one-value-at-a-time loop, which will be welcome, but that's not what the question is about).
I get an error not only I do not understand, but I cannot see how the multiple internet posts about it come into a function within my case.
The error is:
In function 'int main()':....
|error: request for member 'history' in 'coin', which is of non-class type 'coin_t [10]'|
This is my code (true copy-paste from a new project):
#include <iostream>
using namespace std;
// Hand input parameters
const int coinCount=10;
int weight[coinCount]={11,11,9,10,10,10,10,10,10,10};
const int maxDepth=6;
const int caseCount=360;
// GLOBALS
struct coin_t
{
float w;
int history[maxDepth];
int curDepth;
};
coin_t coin[coinCount];
int main()
{
int i,j;
//Initialize coin struct array
for(i=0;i<coinCount;i++)
{
coin[i].w=weight[i];
coin[i].curDepth=-1;
for(j=0;j<maxDepth;j++) coin.history[j]=0; // Here's the error
}
}
coin is an array of struct coin_t with sized coinCount. You need to access by operator[] for the corresponding element in the array.
coin[i].history[j] = 0;
// ^^^
If you want to zero-initialize the history you could do better
struct coin_t
{
float w;
int history[maxDepth]{0};
// ^^^^
int curDepth;
};
by which you can skip the extra looping
for (j = 0; j < maxDepth; j++)
coin[j].history[j] = 0;
That being said C++ offers better std::array. Consider use if its suitable to the case.
#include <bits/stdc++.h>
using namespace std;
int* insertionSort(int* a);
int main()
{
int a[5];
for(int i=0;i<5;i++)
{
cin>>a[i];
}
int b[5];
*b = insertionSort(a);
for(int i=0;i<5;i++)
{
cout<<b[i]<<" ";
}
}
int* insertionSort(int* a)
{
for(int i=1;i<5;i++)
{
int key=a[i];
int j=i-1;
while(j>0 && a[j]>key)
{
a[j]=a[j+1];
j-=1;
}
a[j+1]=key;
}
return a;
}
So this is my code for insertion sort. But when I run this it gives me the error
insertionSort.cpp: In function ‘int main()’:
insertionSort.cpp:15:21: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
*b = insertionSort(a);
I would like to know how does passing and returning arrays in functions work in C++. What is the error in my code?
P.S : It may happen that my insertion code may be wrong. I have not really tested it so pardon me I could not check it because of this error. It would be really helpful if someone can explain it in detail.
insertionSort is returning a int pointer, and you're trying to assign it to an int by dereferencing the pointer (*b). The correct syntax would be
b = insertionSort(a);
Also, b should be declared as int* b
P.S., this compiles, but still doesn't work as intended, but that's a whole different question from the one you posed.
#include <array>
#include <algorithm> // sort
#include <iostream>
constexpr size_t size {5};
std::array<int, size>* insertionSort(std::array<int, size>& a)
{
std::sort(a.begin(), a.end());
return &a;
}
int main()
{
std::array<int, size> a {1, 4, 3, 2, 5};
std::array<int, size>* b = insertionSort(a);
for(size_t i = 0; i < size; ++i)
std::cout << (*b)[i] << std::endl;
}
You should use the standard library functions when possible (here the sort one)
Thanks to C++11 we know have array (instead of playing with raw pointers)
I am trying to learn how to use TBB, so I'm modifying a sample program I found that is designed to compute powers of an array of complex numbers. Originally, it was passing an array into the parallel_for loop, but I am trying to change it so that it passes in a vector. However, I cannot get my code to compile; I get the following error (compiled using g++ -g program_name.cpp -ltbb):
error: passing ‘const std::complex<double>’ as ‘this’ argument
discards qualifiers [-fpermissive] result[i] = z;
My code is below:
#include <cstdlib>
#include <cmath>
#include <complex>
#include <ctime>
#include <iostream>
#include <iomanip>
#include "tbb/tbb.h"
#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/parallel_for_each.h"
#include "tbb/task_scheduler_init.h"
using namespace std;
using namespace tbb;
typedef complex<double> dcmplx;
dcmplx random_dcmplx ( void )
{
double e = 2*M_PI*((double) rand())/RAND_MAX;
dcmplx c(cos(e),sin(e));
return c;
}
class ComputePowers
{
vector<dcmplx> c; // numbers on input
int d; // degree
vector<dcmplx> result; // output
public:
ComputePowers(vector<dcmplx> x, int deg, vector<dcmplx> y): c(x), d(deg), result(y) { }
void operator() ( const blocked_range<size_t>& r ) const
{
for(int i=r.begin(); i!=r.end(); ++i)
{
dcmplx z(1.0,0.0);
for(int j=0; j < d; j++) {
z = z*c[i];
};
result[i] = z;
}
}
};
int main ( int argc, char *argv[] )
{
int deg = 100;
int dim = 10;
vector<dcmplx> r;
for(int i=0; i<dim; i++)
r.push_back(random_dcmplx());
vector<dcmplx> s(dim);
task_scheduler_init init(task_scheduler_init::automatic);
parallel_for(blocked_range<size_t>(0,dim),
ComputePowers(r,deg,s));
for(int i=0; i<dim; i++)
cout << scientific << setprecision(4)
<< "x[" << i << "] = ( " << s[i].real()
<< " , " << s[i].imag() << ")\n";
return 0;
}
You're trying to modify non-mutable member field result in const-qualified operator().
Resolve this discrepancy.
Edit #1: I have already mentioned the two keywords above. Either:
Remove const qualifier from operator():
void operator() ( const blocked_range<size_t>& r ) { ... }
Make result mutable:
mutable vector<dcmplx> result;
Additional erorrs may emerge after applying (although strongly preferred) variant no. 1. No. 2 is just for completeness and is used only in marginal situations.
It indeed results in an error with the 1st variant. This is because tbb::parallel_for takes Func by const&, so it can call only const-qualified member functions on your functor. Why? TBB doesn't want to waste performance by copying large functors (STL passes them by value).
I don't know what's the common practice here, I've never used this library.
Edit #2: Probably all you were missing was that result wasn't a reference:
vector<dcmplx> &result;
Now you'll be able to modify it, even in const-qualified operator(). Modifying a member that gets destructed afterwards wouldn't make sense.
Don't forget to change the constructor's signature to pass y by reference, too.
Off topic issues in your code:
Not included <vector> header
using namespace bulky_namespace globally
not using size_t for i in the for-loop
maybe more...
I wrote the below program to set a value (here it's 3) to some location at memory that is pointed by a pointer named p using a function named f() and print it in the main:
#include <iostream>
using namespace std;
void f(float* q)
{
q=new float;
*q=3;
}
int main()
{
float *p= nullptr;
f(p);
cout<<*p;
return 0;
}
But when I want to compile it, I receive this compile time error :
ap1019#sharifvm:~$ g++ myt.cpp
myt.cpp: In function âint main()â:
myt.cpp:12:11: error: ânullptrâ was not declared in this scope
float *p=nullptr;
^
ap1019#sharifvm:~$
What's wrong?
It seems that pointer literal nullptr is not supported by your compiler.
You may use null pointer constant instead. For example
float *p = 0;
But in any case your program is wrong. It has a memory leak because you store the address of the allocated memory in a local variable of function f that will be destroyed after exiting the function.
The program could look the following way
#include <iostream>
using namespace std;
void f( float **q)
{
*q = new float;
**q = 3;
}
int main()
{
float *p = 0;
f( &p );
cout << *p;
delete p;
return 0;
}
Or you could use reference to the pointer. For example
#include <iostream>
using namespace std;
void f( float * &q)
{
q = new float;
*q = 3;
}
int main()
{
float *p = 0;
f( p );
cout << *p;
delete p;
return 0;
}
nullptr is only supported from gcc-4.6 or later.
You can easily workaround that with a const void *nullptr=(void*)0;, but to avoid later problems with a gcc upgrade, I suggest to
upgrade your gcc (4.6 is quite old)
or don't use it.
It is only syntactic sugar, you don't need that.
The word null is not reserved by the C++ standard.
Use NULL instead.