Convert vector of vector to pointer of pointer - c++

Assume I have a C library API function which takes pointer of pointers as parameter. However since I am programming in C++ I would like to take advantage of std vector to deal with the dynamic memory. How can I efficiently convert vector of vector into pointer of pointer? Right now I am using this.
#include <vector>
/* C like api */
void foo(short **psPtr, const int x, const int y);
int main()
{
const int x = 2, y = 3;
std::vector<std::vector<short>> vvsVec(x, std::vector<short>(y, 0));
short **psPtr = new short*[x];
/* point psPtr to the vector */
int c = 0;
for (auto &vsVec : vvsVec)
psPtr[c++] = &vsVec[0];
/* api call */
foo(psPtr, x, y);
delete[] psPtr;
return 0;
}
Is this the best way to achieve the goal? Can I get rid of the "new delete" thing by using iterator or some std method in this case? Thanks in advance.
Edit:
According to answers I am now using this version to interface with C code. I am posting it here.
#include <vector>
/* C like api */
void foo(short **psPtr, const int x, const int y);
int main()
{
const int x = 2, y = 3;
std::vector<std::vector<short>> vvsVec(x, std::vector<short>(y, 0));
std::vector<short*> vpsPtr(x, nullptr);
/* point vpsPtr to the vector */
int c = 0;
for (auto &vsVec : vvsVec)
vpsPtr[c++] = vsVec.data();
/* api call */
foo(vpsPtr.data(), x, y);
return 0;
}
Looks more C++ like to me. Thanks for all!

Is this the best way to achieve the goal?
If you are sure that the vector of vectors will outlive psPtr, then yes. Otherwise, you run the risk that psPtr will contain invalid pointers.
Can I get rid of the "new delete" thing by using iterator or some std method in this case?
Yes. I suggest using:
std::vector<short*> psPtr(vvsVec.size());
and then use &psPtr[0] in the call to the C API function. That removes the burden of memory management from your code.
foo(&psPtr[0]);

std::vector<short*> vecOfPtrs;
for (auto&& vec : vvsVec)
vecOfPtrs.push_back(&vec[0]);
foo(&vecOfPtrs[0]);

Related

Matrix of pointers using subscription

So a few days ago I asked and received a very good answer in this thread. Assignment and retrieval using subscript and equals operator overloads
Unfortunately my mistake but it was a little to far from my end use scenario, I'm trying to store pointers to the cchar_t class in nucrsesw/ncurses.h This is what I have currently
#include <iostream>
#include <vector>
#include <string>
#include <ncursesw/ncurses.h>
#include <ncursesw/panel.h>
class Matrix {
std::vector<std::vector<cchar_t*>> m;
public:
Matrix(int x = 0, int y = 0) {
m.resize(x);
for (int i = 0; i < x; ++i)
m[i].resize(y);
}
class Proxy {
std::vector<cchar_t*> &mm;
public:
Proxy(std::vector<cchar_t*> &c) : mm(c) {}
cchar_t& operator[](int index) {
return *mm[index];
}
};
Proxy operator[](int index) {
return Proxy(m[index]);
}
};
int main() {
wchar_t wR = u'W';
cchar_t *w;
setcchar(w, &wR, 0, COLOR_PAIR(0), NULL);
Matrix m(1, 1);
m[0][0] = *w;
std::cout << typeid(m[1][1]).name() << std::endl;
}
I keep getting invalid initialization of reference type in the second subscript overload function. It may be obvious but CPP is not my primary language. Does anyone know how this can be adapted to store pointers? Thanks in advance.
Note the code is edited to show exactly what happens when it seg faults on me.
mm is a reference to an std::vector which holds objects of type cchar_t* (pointers to cchar_t objects). The subscript operator of std::vector returns a reference to the object at the appropriate index. In your case, that would be a reference to a pointer to cchar_t.
To fix your problem, you can dereference the obtained pointer in the return statement: simply change it to return *mm[index];.

Run-Time Check Failure #2 - Stack around the variable 'e' was corrupted. occurred

#include<iostream>
#include <list>
using namespace std;
class Euler {
private:
int korifes = 0;
int akmes = 0;
int* pinakas[];
public:
void print() { cout << *pinakas[0]; return; }
Euler(int korifess, int akmess);
~Euler() { delete[] *pinakas; }
void addAkmes(int kor1, int kor2);
};
Euler::Euler(int korifess, int akmess) : akmes(akmess), korifes(korifess) {
*pinakas = new int(korifes);
*pinakas[0] = 89;
}
int main() {
Euler e(2, 1);
e.print();
}
Run-Time Check Failure #2 - Stack around the variable 'e' was corrupted. occurred...i can not find where i am wrong in my code.
There are a number of errors in your code, all related to the nature of the pinakas member variable. As it stands, you are declaring this as an array of pointers (to int), and, furthermore, you are using a non-standard syntax for 'flexible' arrays (the empty []).
I don't normally just paste 'fixed' code as an answer but, in this case, that code (with the added \\\ comments where I've made changes) is likely to be the most succinct way to help you.
Although, as many here will no doubt point out, it is far better to avoid the use of 'raw' pointers and the new and delete operators, and use the std::vector container, instead.
#include <iostream>
#include <list>
//using namespace std;/// This is considered 'bad practice' by many programmers
using std::cout;/// Just use the aspect of the STL that you need!
class Euler {
private:
int korifes = 0;
int akmes = 0;
int* pinakas;/// This will point an 'array' of integers
public:
void print() {
cout << pinakas[0]; return;/// No longer any need for the dereference (*)
}
Euler(int korifess, int akmess);
~Euler() {
delete[] pinakas;/// No need for the dereference (*)
}
// void addAkmes(int kor1, int kor2);/// You haven't provided an actual definition for this, but your never use it!
};
Euler::Euler(int korifess, int akmess) : akmes(akmess), korifes(korifess)/// NOTE: Members are initialized in DECLARATION order!
{
pinakas = new int[korifes];/// Use "[]" (not "()") to allocate an array!
pinakas[0] = 89;/// No need for the dereference (*)
}
Feel free to ask for any further clarification and/or explanation.

C++ - Return multidimensional array from function

I am writing a code for Cellular Automata and I need an evolution function to calculate the state of the automata after a time step.
I choose to call this function evol, to test it I created an elementary function in C++. Unfortunately it does not compile since the compiler cannot understand that I need it to return an array. Here is the code :
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
const int N = 51; // Size of the grid; two columns/rows are added at the beginning and the end of the array (no evolution of the CA on the boundaries)
class Cell{
//defining whats a cell here
};
void showCA(Cell CA[N+2][N+2]){
//function to print the CA grid in the terminal
}
Cell[N+2][N+2] evol(Cell CA[N+2][N+2]){
return CA;
}
int main()
{
// Initialisation
cout << "Initialisation" << endl;
static Cell CA[N+2][N+2];
// some code here to initialize properly the Cell array.
showCA(CA);
CA = evol(CA);
showCA(CA);
return 0;
}
The compiler returns this error :
error: expected unqualified-id
Cell[N+2][N+2] evol(Cell CA[N+2][N+2]){
Any idea on how I should implement this ?
You cannot return arrays from functions:
ยง 8.3.5/8
Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things.
If you are wishing to return raw, C-style arrays from functions, then you have to use a reference or pointer. For example, here's how it is done using a reference (you can do the same using a pointer by replacing & with *):
Cell (&evol(Cell (&CA)[N+2][N+2]))[N+2][N+2];
However, this is very unintuitive and hard to read. If your compiler supports the latest standard (C++11) the return type can be cleaned up using a trailing return type:
auto evol(Cell (&CA)[N+2][N+2]) -> Cell(&)[N+2][N+2];
But again, this is probably still harder to read.
C++11 facilitates the handling of C-style arrays with the container std::array<>. Non-C++11 code should use std::vector<>:
using Cells = std::array<std::array<Cell, N+2>, N+2>;
Cells const& evol(Cells const& CA);
You can use
typedef std::vector<std::vector<Cell>> CellArray;
CellArray Cells(N+2); // resize main dimension
for (size_t i=0; i<N+2; i++)
Cells[i].resize(N+2); // resize all cells of main dimension
to hold your cell array, but you also need to add a copy constructor and operator= in Cell class
class Cell {
public:
Cell() { ... default ctor code here ... }
Cell(const Cell &c) { *this = c; }
Cell &operator=(const Cell&c)
{
if (this != &c)
{
... copy data from c members to this members here ...
}
return *this;
}
};
Your evol function then can return a CellArray:
CellArray evol(CellArray &c)
{
CellArray r;
... do some calculations with c and r ...
return r;
}
once you have declared a variable using the array syntax like you have:
Cell CA[N+2][N+2];
you cannot assign CA to be something else. You can only assign values to its contents. Hence,
CA = evol(CA);
is wrong.
You can do the following:
Cell (*CA2)[N+2] = evol(CA);
As the number of elements seems to be fixed, I suggest you use the std::array container:
const int N = 51;
typedef std::array<std::array<Cell,N+2>, N+2> datatype;
You can then use this type as a return type:
datatype Evol( const datatype& d );
You can access elements just as if it was a "C" array:
datatype d;
Cell c;
d[10][20] = c;
I would strongly suggest encapsulate your array into a class. You cannot return an array, but you can return an object that contains an array.

foreach in C++ int array

I am new to C++ and I am writing the following code.
I needed to iterate over all the addons in my calling function - testFunction. I know this works in C#, but this code is not working. Can anyone please point out the right way to do it in C++?
#include "stdafx.h"
#include <iostream>
#include "resource.h"
int testFunction(char* tester);
int _tmain()
{
int mainProd=2;
int Addons[]={7,8,9,10};
testFunction(mainProd,Addons);
}
void testFunction(int mainProd,int addons[])
{
for(int x = 0 ; addons.length;++x) ---- Not working
{
std::cout<< addons[x];
}
}
I tried to implement vector as below suggestions by you guys
#include "stdafx.h"
#include <iostream>
#include "resource.h"
#include <vector>
void testFunction(std::vector<int> addons);
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<int> Addons ;
for(int i = 0 ;i<10;++i)
{
Addons.push_back(i);
}
testFunction(Addons);
}
void testFunction(std::vector<int> addons)
{
for(int i =0 ; i<addons.size();++i)
{
std::cout<<addons.at(i);
}
}
An array (a raw array) decays into a pointer when passed as an argument to a function, so your array has no size information.
You need to pass the length of the array explicitly into the function to know it inside the function.
Alternatively, and better, use a std::vector and then you'll have the .size() always available when needed.
Apart from using vectors, as Tony suggests, you can use templates and pass the array by reference so that the compiler will deduce the array's size:
template<int N>
void testFunction(int mainProd,int (&addons)[N])
{
for(int x = 0; x < N; ++x) // ---- working
{
std::cout<< addons[x];
}
}
You're using concepts of C# in C++ but, even if we assume that both languages are similar, they're not equal.
The syntax for a ranged-for in C++ is the following:
for (type identifier : container) // note the ':', not ';'
{
// do stuff
}
You can use this for flavour if you have a C++11 compiler.
Btw, it seems that you're using properties on your code:
for(int x = 0 ; addons.length;++x) // what is lenght?
{
std::cout<< addons[x];
}
There's no such thing in C++, if you want to call an object method you need to call it as a function:
// assuming that the object 'addons' have a method
// named 'length' that takes no parameters
addons.length();
But the addons variable isn't an object, is an array (take a look to this tutorial), so it doesn't have a method or property named length; if you need to know its length in order to iterate it you can use in some contexts the sizeof operator (see the tutorial for more information).
Let's suppose that addons were a container:
typedef std::vector<addon> Addons;
Addons addons;
If you want to iterate it using the C++11 range-for, you can write it as follows:
for (addon a : addons)
{
// do stuff with a.
}
Hope it helps.
If you were to use a std::vector or std::array, you could use std::foreach,
std::vector<int> addons = {7,8,9,10};
std::array<int, 4> addons = {7,8,9,10}; // Only use one of these...
std::foreach(addons.begin(), addon.end(), [](int i) {
std::cout << i
});
Code is working with this
for (int i = 0; i < (end(array) - begin(array)); i++)
Return maximum size
Test whether array is empty
array::empty
Element of array
array::size
Array size
sizeof()
If you don't want to use any STL container, you just need to pass the array by reference to the function. Problem here is that you can't define such argument without exact size of the array. This restriction you can overcome making the function as a template, defining the size as the template parameter:
#include <iostream>
template<int N>
void testFunction(int mainProd,int (&addons)[N])
{
for(int x = 0 ; x < N; ++x)
{
std::cout<< addons[x];
}
}
int main()
{
int mainProd=2;
int Addons[]={7,8,9,10};
testFunction(mainProd,Addons);
return 0;
}

Passing pointer to 2D array c++

I'm having this problem for quite a long time - I have fixed sized 2D array as a class member.
class myClass
{
public:
void getpointeM(...??????...);
double * retpointM();
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A ); ???
A = moo.retpointM(); ???
}
I'd like to pass pointer to M matrix outside. It's probably very simple, but I just can't find the proper combination of & and * etc.
Thanks for help.
double *A[3][3]; is a 2-dimensional array of double *s. You want double (*A)[3][3];
.
Then, note that A and *A and **A all have the same address, just different types.
Making a typedef can simplify things:
typedef double d3x3[3][3];
This being C++, you should pass the variable by reference, not pointer:
void getpointeM( d3x3 &matrix );
Now you don't need to use parens in type names, and the compiler makes sure you're passing an array of the correct size.
Your intent is not clear. What is getpointeM supposed to do? Return a pointer to the internal matrix (through the parameter), or return a copy of the matrix?
To return a pointer, you can do this
// Pointer-based version
...
void getpointeM(double (**p)[3][3]) { *p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(double (*&p)[3][3]) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
For retpointM the declaration would look as follows
...
double (*retpointM())[3][3] { return &M; }
...
int main() {
double (*A)[3][3];
A = moo.retpointM();
}
This is rather difficult to read though. You can make it look a lot clearer if you use a typedef-name for your array type
typedef double M3x3[3][3];
In that case the above examples will transform into
// Pointer-based version
...
void getpointeM(M3x3 **p) { *p = &M; }
...
int main() {
M3x3 *A;
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(M3x3 *&p) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
// retpointM
...
M3x3 *retpointM() { return &M; }
...
int main() {
M3x3 *A;
A = moo.retpointM();
}
The short answer is that you can get a double * to the start of the array:
public:
double * getMatrix() { return &M[0][0]; }
Outside the class, though, you can't really trivially turn the double * into another 2D array directly, at least not in a pattern that I've seen used.
You could create a 2D array in main, though (double A[3][3]) and pass that in to a getPoint method, which could copy the values into the passed-in array. That would give you a copy, which might be what you want (instead of the original, modifiable, data). Downside is that you have to copy it, of course.
class myClass
{
public:
void getpointeM(double *A[3][3])
{
//Initialize array here
}
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A );
}
You may want to take the code in your main function which works with the 2D array of doubles, and move that into myClass as a member function. Not only would you not have to deal with the difficulty of passing a pointer for that 2D array, but code external to your class would no longer need to know the details of how your class implements A, since they would now be calling a function in myClass and letting that do the work. If, say, you later decided to allow variable dimensions of A and chose to replace the array with a vector of vectors, you wouldn't need to rewrite any calling code in order for it to work.
In your main() function:
double *A[3][3];
creates a 3x3 array of double* (or pointers to doubles). In other words, 9 x 32-bit contiguous words of memory to store 9 memory pointers.
There's no need to make a copy of this array in main() unless the class is going to be destroyed, and you still want to access this information. Instead, you can simply return a pointer to the start of this member array.
If you only want to return a pointer to an internal class member, you only really need a single pointer value in main():
double *A;
But, if you're passing this pointer to a function and you need the function to update its value, you need a double pointer (which will allow the function to return the real pointer value back to the caller:
double **A;
And inside getpointM() you can simply point A to the internal member (M):
getpointeM(double** A)
{
// Updated types to make the assignment compatible
// This code will make the return argument (A) point to the
// memory location (&) of the start of the 2-dimensional array
// (M[0][0]).
*A = &(M[0][0]);
}
Make M public instead of private. Since you want to allow access to M through a pointer, M is not encapsulated anyway.
struct myClass {
myClass() {
std::fill_n(&M[0][0], sizeof M / sizeof M[0][0], 0.0);
}
double M[3][3];
};
int main() {
myClass moo;
double (*A)[3] = moo.M;
double (&R)[3][3] = moo.M;
for (int r = 0; r != 3; ++r) {
for (int c = 0; c != 3; ++c) {
cout << A[r][c] << R[r][c] << ' ';
// notice A[r][c] and R[r][c] are the exact same object
// I'm using both to show you can use A and R identically
}
}
return 0;
}
I would, in general, prefer R over A because the all of the lengths are fixed (A could potentially point to a double[10][3] if that was a requirement) and the reference will usually lead to clearer code.