In CPP I use a C library, one of the method needs a const void ** as parameter.
In my class I have a property whose type is void *.
I tried to call the function by doing function(&my_property) but the compiler complained that it could not convert a void ** to a const void **.
To fix this issue I used a const cast and did function(const_cast<const void *>(&my_property)).
I try to avoid casting as much as possible and I would like to know if there is a "clean" way to do that without using a const cast.
Proper solution would be to turn my_property into const void*. Otherwise you might break a contract of function.
Replicating your situation in a simple manner, let's say you have this code:
void function(const void **p)
{
//...
}
int main()
{
void *my_property;
function(&my_property);
}
Using const_cast is safe, I don't think it's all that unclean, but you have alternatives, the best of wich would be to turn my_property into a const void*, suspecting that may not be an option, you may just use a const void* pointer to wich you would assign the original void*:
void *my_property;
const void *pp = my_property;
function(&pp);
The conversion is still there, but it's implicit.
As Quentin very accurately pointed out, this does not make a lot of sense, unless it's just to shut up the compiler.
If the library is expecting an array of arrays using a cast probably wont fix it, if you can't check the library source you can guess. A manual conversion is a safe solution.
Using new_cast_a_to_m() requires you to delete the array at some point but not the original array; struct X and the code aroud it is just for this example, new_cast_a_to_m() should work for you by itself.
#include <iostream>
struct X {
int a = 0;
};
int c_foo (X ** x){
return x[4][0].a;
}
template <typename V>
V ** new_cast_a_to_m(V * arr, size_t n){
V ** nc = new V * [n];
for(size_t i=0; i < n; i++){
nc[i] = &arr[i];
}
return nc;
}
int main(void){
X ** arr = new X * [5];
arr[4] = new X;
std::cout << "intended c_foo() -> " << c_foo(arr) << std::endl;
X * brr = new X[5];
X ** nrr = new_cast_a_to_m(brr, 5);
std::cout << "casted c_foo() -> " << c_foo(nrr) << std::endl;
delete [] nrr;
delete arr[0];
delete [] arr;
return 0;
}
Related
I see this being commonly used in file handling, (char*)&obj.
There are so many casting methods available since C++11,like static cast, cant we employ one over these ?
The & sign is there to take the address of obj.
Example:
#include <cstdio>
void printData(const char* p, int n) {
for(int i = 0; i < n; i++)
printf("byte %2d : %d\n", i, (int)p[i]);
}
struct DataStruct {
int x;
int y;
};
int main() {
DataStruct obj;
obj.x = 5;
obj.y = 257;
char* dataPtr = (char*)&obj;
printData(dataPtr, sizeof(DataStruct));
return 0;
}
where the (char*)&obj maneouver is used to get a char* that can be passed to the printData function which just wants an array of chars to print.
In that example, the line
char* dataPtr = (char*)&obj;
could instead have been written using reinterpret_cast like this:
char* dataPtr = reinterpret_cast<char*>(&obj);
which would do the same thing. An advantage of using reinterpret_cast instead of the cryptic (char*)&obj is that when you write reinterpret_cast it becomes more clearly visible that you are doing something kind of strange and possibly dangerous at that point in the code.
How correctly declare pointers, allocate memory, and send them as parameters in fuctions to write values ? The code below is what I tried but it doesn't work correctly. I need the same logic. I mean declare, set, then show.
...
struct complex {
int i;
int r;
};
void set(complex *n, int i, int r){
n = new complex;
n->i = i;
n->r = r;
}
void show(complex *n){
std::cout << n->i << " " << n->r;
}
int main(int argc, char* argv[])
{
complex *n;
set(n,10,20);
show(n);
system("pause");
return 0;
}
Actually, your function set couldn't work, because by doing
n = new complex;
whatever the pointer you pass to the function, the pointer will be overwritten by the pointer on the new object.
You can pass the pointer via reference (on C++ only...) like that
void set(complex* &n, int i, int r)
And by doing so you'll modify the value of the original pointer.
You can also simply return the pointer by a return n
But obviously if the prototype of your function must stay like that, it's not possible...
Or, but it's highly discouraged, as many said, you can use a double pointer, and it's quite tricky !
If I don't make mistake, you create a
complex** n
You pass it to your function
set(complex** n, int i, int r)
And then you load
*n = new complex
And it must work if you pass *n to all your function instead of n...
And don't forget to delete your object at the end ;)
Remove the initialization part from set function and put it in the main function.
see this link for explanation.
Why can I not initialize an array by passing a pointer to a function?
Check this code
//#include<windows.h>
#include <iostream>
using namespace std;
struct complex {
int i;
int r;
};
void set(complex *n, int i, int r) {
// n = new complex;
n->i = i;
n->r = r;
}
void show(complex *n) {
std::cout << n->i << " " << n->r;
}
int main(int argc, char *argv[]) {
complex *n = new complex();
set(n, 10, 20);
show(n);
delete n;
//system("pause"); TRY TO AVOID THIS. MAKES YOUR CODE LESS PORTABLE.
return 0;
}
see this link.
c++ - system("pause"); - Why is it wrong? - Stack Overflow
Background: I'm stuck to arm-arago-linux-gnueabi-g++ (GCC) 4.3.3. Although answers that requires C++11 or later is also appreciated, please explicitly express any language requirement later than C++03.
The object's constructor fills values into tables to be used by the algorithm.
As those table does not change and are not supposed to be changed, I want the them to be const, how do I do that?
Difficulty #1, the values are computationally generated, and I don't want to hard code them in a source file.
Difficulty #2, the computing sometimes depends on inputs that are only available at runtime.
Difficulty #3, I don't know why but I don't want the array to be static, even though the values might be the same for all objects(cases where the values does not depend on runtime input).
Difficulty #4, it's an array, so initializer list in C++03 won't work.
Edit1:
A few weeks after this post, I found both std::array and std::vector are very good alternative to C-style array when std::array is not available.
You can encapsulate the tables in a private type, with a single const instance of that type in your object, then forward the relevant constructor parameters to the private object; this works because even a const object is non-const during its construction.
For example:
class MyClass {
const struct Tables {
double x[1000];
double y[200];
Tables(int i, double d) {
x[i] = d;
y[200 - i] = -d;
}
} tables;
public:
MyClass(int i, double d) : tables(i, d) {}
};
MyClass c(20, 5.5);
Another technique is to build the tables in an ephemeral mutable array whose lifetime is bounded by the lifetime of the constructor, then initialize the const array from those mutable arrays.
Using C++11 std::array (since array types can't be copy-initialized):
class MyClass {
static std::array<double, 1000> buildArray(...) {
std::array<double, 1000> array;
... // fill array
return array;
}
const std::array<double, 1000> mArray;
public:
MyClass(...) : mArray(buildArray(...)) {}
};
Note that std::array is easy to express in C++03; it doesn't depend on any C++11 language features.
If you're worried about the overhead of returning a large array, instrument it - even C++03 compilers are capable of optimising large array returns.
I think you could implement a class containing the actual non const array. That way you can easily compute the values in a constructor.
Then this class would only have to implement the operator[] to be usable as an array. Or it could also simply return a const reference to the array.
Implementation example :
#include <iostream>
using namespace std;
class const_array {
int *arr;
size_t size;
public:
const_array(size_t size, int typ): size(size) {
arr = new int[size];
size_t i;
int val = 0;
for (i=0; i<size; i++) {
val += typ;
arr[i] = val;
}
}
const_array(const const_array & src): size(src.size) {
arr = new int[size];
size_t i;
for (i=0; i<size; i++) {
arr[i] = src.arr[i];
}
}
~const_array() {
delete[] arr;
}
const int * const getArray() const {
return arr;
}
int getSize() const {
return size;
}
const int& operator[](int i) {
return arr[i];
}
};
int main() {
const_array a(16, 4);
// int *arr = a.getArray(); error
const int *arr = a.getArray();
int j = a[2];
int k = arr[2];
// int * pj = &(a[2]); error
const int * pj = &(a[2]);
const int * pk = &(arr[2]);
cout << "a[2]=" << j << " (" << pj << ") - a.getArray[2]="
<< j << " (" << pj << ")" << endl;
return 0;
}
Should be a simple question, I have a struct
struct Foo{
float *bar;
Foo(){
bar = 0;
}
};
and a load function:
bool loadFoo(Foo *data){
float nums[4] = {0,1,2,3};
data->bar = nums;
return true;
};
And I run it like this:
void main(){
char data;
Foo myFoo;
loadFoo(&myFoo);
std::cerr << sizeof(myFoo.bar) << "\n";
std::cerr << myFoo.bar[0] << "\n";
std::cerr << myFoo.bar[1] << "\n";
std::cerr << myFoo.bar[2] << "\n";
std::cerr << myFoo.bar[3];
std::cin >> data;
};
and the output is 4 bytes for the sizeof(myFoo->bar) I thought by passing the struct to the method I could modify data->bar and since bar is, float *bar; I could make it an array since I cant specify that bar is an array because its an 'unknown size' when loaded. (when implemented the program will read in values from a file) This works fine with non pointer variables but its the pointer that I can't seem to understand.
How do I make it so that when I pass the struct I can modify the variable pointer?
any help would be greatly appreciated!
You can do something like you've specified, but the exact implementation you've given will encounter undefined behavior.
bool loadFoo(Foo *data){
// Create an array of 4 floats ON THE STACK.
float nums[4] = {0,1,2,3};
// point data->bar at the above slice of stack.
data->bar = nums;
return true;
// abandon the piece of stack we're pointing at.
}
You might want to look into std::vector as a growable way of storing runtime sizes arrays, or you will need to allocate backing store for the destination floats, e.g.
data->bar = new float[4];
and free it when you are done with it
delete data->bar;
That said; it would seem more elegant to do these operations as members of Foo.
#include <vector>
// #include <algorithm> // (for the std::copy option)
class Foo
{
std::vector<float> m_floats;
public:
Foo() : m_floats() {}
void loadFloats()
{
m_floats = { 0, 1, 2, 3 };
}
// or load them from someplace else
void loadFloats(float* srcFloats, size_t numFloats)
{
m_floats.clear();
m_floats.reserve(numFloats);
// copy by hand:
for (size_t i = 0; i < numFloats; ++i) {
m_floats.push_back(srcFloats[i]);
}
// or just:
// std::copy(srcFloats, srcFloats + numFloats, m_floats);
}
};
You haven't specified the problem but let me guess - it crashes and/or doesn't yield the result you expect. The reason for that is assigning a pointer to a local variable in the line data->bar = nums; Here you link your data->bar to a nums array which is allocated on stack and is freed when you exit loadFoo. The result is a dangling pointer inside your Foo object.
You can solve this in different ways. The most straightforward would be to use a constructor with size parameter - this will solve your unkonwn size issue. You'll need to explicitly allocate memory for the data->bar and copy the data into the allocated space (of course, it will require to free it when not in use anymore). Same effect can be achieved by using your loadFoo func but using internal language features (constructor/destructor) is much cleaner.
Instead of loadFoo you can have constructor
struct Foo{
float *bar;
Foo( int size){
bar = new float[size]; //allocate memory
//... Initialize bar
}
~Foo() { delete bar;}
};
OR using initializer_list
#include <initializer_list>
struct Foo{
float *bar;
Foo( std::initializer_list<float> l){
bar = new float[l.size()]; //allocate memory
std::initializer_list<float> ::iterator it = l.begin();
size_t i=0;
for(;it!=l.end();++it,++i)
bar[i] = *it;
}
~Foo() { delete bar;}
};
Also, make sure you follow rule of three
#include <iostream>
template<class T> T CreateArray(T a, int n)
{
a = new T [n]; // mistake: double* = double**
return a;
}
int main()
{
double* a;
int n = 5;
a = CreateArray(a,n);
return 0;
}
can I allocate memory using a template and new? And what my mistake?
Your code has some wrong things. First, you can do something like what you're trying to do, but you should write something like this:
template<class T> T* CreateArray(int n)
{
T* a = new T [n];
return a;
}
int main()
{
double* a;
int n = 5;
a = CreateArray<double>(n);
return 0;
}
Note that you don't have to pass the a array (it will be copied inside CreateArray, and its changes won't be visible inside main). Note also that you define the template to returning a pointer T*, that is what main() a is expecting.
So others have explained why your code doesn’t work and how it can be improved.
Now I’ll show how you can still get the following code to compile – and to work properly:
double* a = CreateArray(5);
int* b = CreateArray(7);
The problem, as already mentioned, is that C++ does not infer template arguments from return types alone.
You can circumvent this limitation by making the above function return a simple proxy object. The proxy object has a single operation: an (implicit) conversion to T*. This is where the actual allocation happens.
The CreateArray function is therefore very simple (and not a template):
CreateArrayProxy CreateArray(std::size_t num_elements) {
return CreateArrayProxy(num_elements);
}
As for the proxy:
struct CreateArrayProxy {
std::size_t num_elements;
CreateArrayProxy(std::size_t num_elements) : num_elements(num_elements) { }
template <typename T>
operator T*() const {
return new T[num_elements];
}
};
Easy as π.
Now, should you use this code? No, probably not. It offers no real advantage over direct allocation. But it’s a useful idiom to know.
You want to accept a pointer to the type you want to allocate:
template<class T> T* CreateArray(T* a, int n)
{
a = new T [n];
return a;
}
This should do the trick.
I prefer to keep empty pointers value NULL.
#include <iostream>
template<class T> bool CreateArray(T * &a, int n)
{
if ( a != 0 )
return false;
a = new T [n];
return true;
}
int main()
{
double* a = 0;
int n = 5;
CreateArray(a,n);
return 0;
}
vector could be a good solution, too. I think it is better one, because you won't make memory leak(s).
#include <vector>
int main()
{
std::vector<double> a;
int n = 5;
a.resize(n);
return 0;
}