C++ - problems with vector pointers - c++

Imagine I want to manipulate a single vector with the content of two current vectors, such as:
vector<double> b(5),c(5);
vector<double*> point;
for (int i; i<5; i++) point.push_back(new double(b[i]));
for (int i; i<5; i++) point.push_back(new double(c[i]));
That's nice until here. How would one manipulate such vector?
I have been trying variations of:
point[7] = 33.12;
I am pretty sure I am missing something about reference since "point[7]" will be a memory address.

Since this is a vector of pointers, the subscript operator returns a pointer:
*point[0] = 33.12; // Assigns new value to the pointer
// Equivalent: *(point[0]), fetch a pointer and dereference it
For example:
vector<double*> point;
double d = 3.14;
point.push_back(&d);
*point[0] = 1.61;
std::cout << *point[0] << std::endl; // Prints 1.61
P.S. as specified in comments to the question, note the: int i in your for loop.

Related

Assign new vector to vector returned from function in C++

I have a function in C++ that takes a vector, and constructs a vector of the same size with modified values, then returns it:
vector<double> sigmoid_from_vector(vector<double> v){
int size = (v.size());//redundant but helps
vector<double> sigvec(size);//Create empty vector to store sigmoid values
for (int i = 1; i<=size; i++) {
sigvec[i] = 1/(1+exp(-1*v[i]));
//cout << "sig val calculated: " << sigvec[i] << endl;
}
return sigvec;
}
I cannot, for the life of me, use the returned vector. So for I have tried the following lines, that to my knowledge should work:
vector<double> testsig = sigmoid_from_vector(age_train);
vector<double> testsig = move(sigmoid_from_vector(age_train));
edit: I should go to bed. Thank you everyone
There are several problems with you given program.
Problem 1
Since you're using i<=size instead of i<size you'll go out of bound of the vector leadingto undefined behavior.
Additionally note that vector indexing starts from 0 and not 1 so you can replace int i = 1 with int i = 0.
Problem 2
Moreover, there is no need to create a separate vector named sigvec as v is already a local copy of the passed vector.
Thus the total changes are as follows:
vector<double> sigmoid_from_vector(vector<double> v){
//---------------v--------------------->0 instead of 1
for (int i = 0; i<size; i++) {
//-------------------^----------------->< instead of <=
//other code here using v instead of sigvec
}
return v;
}

C++ Void double pointer interference with another

I am trying to do a project that involves overloading new and delete. I am storing an array of void pointers (pointers to random memory that is allocated) in a double void pointer. Of course, this array will need to be resized to account for further void pointers that come in.
This is the intialization of the array, allocArraySize(int) is set to 4.
void** allocArray = (void**) calloc ( allocArraySize, sizeof(void*) );
Setting all values to nullptr..
for(int i=0; i<allocArraySize; i++){ *(allocArray + i*sizeof(void*)) = nullptr; }
However, when trying to resize the array, I noticed that my original array of void pointers is modified when I create a new temporary array(temp) to store them in.
// PRINTS THE ORIGINAL ARRAY
for(int i=0; i<allocArraySize; i++){std::cout<<i<<" = "<<*( allocArray + i*sizeof(void*))<<"\n";}
void** tempArray = (void**)calloc(allocArraySize, sizeof(void*));
// PRINTS THE ORIGINAL ARRAY
for(int i=0; i<allocArraySize; i++){std::cout<<i<<" = "<<*( allocArray + i*sizeof(void*))<<"\n";}`
Notice, I am not even putting the array values in the temp array yet and I am still getting this problem. Why is that? why is this random value being assigned to this spot when it is indeed initialized? How is this one new temp array variable messing with my array?
NOTE: This is basically the complete code. Only thing missing is a main function, iostream, and the declaration for allocArraySize. Yes, WELL aware that I am not freeing these poor double pointers. I just wanted to create the problem in simplest terms possible.
The sizeof multiplier shouldn't be there:
*(allocArray + i*sizeof(void*))
// ^^^^^^^^^^^^^^ this shouldn't be here
void** is strongly typed. It participates in proper offset calculation via pointer arithmetic. There is no need here for sizeof offset calculations. That loop, which appears to be crafted to dump the pointer values in the sequence, should therefore be:
for(int i=0; i<allocArraySize; i++)
{
std::cout<< i << " = " << allocArray[i] << "\n";
}
You are indexing the pointers incorrectly i * sizeof(void*) rather than i.
for(int i=0; i<allocArraySize; i++){ allocArray[i] = nullptr; }
Firstly, you rather shouldn't use calloc in C++ code. Especially if you program uses both new expression and calloc\malloc, it may lead to to UB due to mismatching deletors.
allocArraySize got type void** , so it's pointer to pointer. Result of expression *allocArraySize got same sizeof as void* or uintptr_t type. Arithmetic with pointers automatically increment pointer by amount required to point at next object of same type.
C++ way to write it doesn't even require such arcane knowledge either, all you should do is to use a new expression and list-initialize it with empty list to get same effect as calloc does in C.
void** allocArray = ::new void*[allocArraySize] {};
for(int i = 0; i < allocArraySize; ++i)
{
std::cout<< i << " = " << allocArray[i] << "\n";
}
When using new/delete from within of overloaded one, it's essential to use :: or it would lead to infinite recursion.
allocArray[i] is an equivalent of *(allocArray + i)
Overloading new\delete aside. But truly C++ way to do that is to avoid naked pointers and use containers if possible. New\delete might be wrappers around usage of some memory pool class.
// do we really need a vector of pointers?
auto allocArray = std::vector<void*>(allocArraySize, nullptr);
int i = 0;
for( auto &v : allocArray )
std::cout<< (i++) << " = " << v << "\n";
In C++20 range-based for loop becomes more contained thanks to init-statement
for(int i = 0; auto &v : allocArray )
std::cout<< (i++) << " = " << v << "\n";

surprising constructors for a class!

What is the problem here in this code?
It gives segmentation fault. I found value of size in vector (int *a)
is no more 3. How is this?
#include <iostream>
using namespace std;
class vector
{
int *v;
int size;
public:
vector(int m)
{
v = new int[size = m];
for(int i=0; i<size; i++)
v[i] = 0;
}
vector (int *a)
{
for(int i=0; i<size; i++)
v[i] = a[i];
}
int operator*(vector &y)
{
int sum = 0;
for(int i=0; i<size; i++)
sum += this -> v[i] * y . v[i];
return sum;
}
};
int main()
{
int x[3] = {1,2,3};
int y[3] = {4,5,6};
vector v1(3);
vector v2(3);
v1 = x;
v2 = y;
int R = v1 * v2;
cout << "R = " << R;
return 0;
}
Sincerely,
Srinivas Nayak
Apart for the problem with the allocation in your constructor vector (int *a), you also need an overloaded assignment operator:
int operator=(int *a) {
for(int i=0; i<size; i++)
v[i] = a[i];
}
Since the following two make use of it:
v1 = x;
v2 = y;
This is not surprising at all.
Your first constructor seems ok, the second one does miss the allocation for v.
Edit: v1 = x and v2 = y doesn't make sense without overloading operator=.
In essence the reason it generates a fault is in the line
v1=x;
As you have no assignment operator this in effect becomes:
v1=vector(x)
Which called your int * constructor. This constructor runs with size initialised to garbage which causes the seg fault as the loop progresses towards invalid memory.
Strategically the problem is you want create a new object for a int * but you don't know how big the array is that you are pointing at.
Your code looks like you want to assume that the array is the correct size for the currently defined vector in which case the operator you want to define this function in preference to the constructor: operator=(int *)
You generally seem a bit confused about which object is which for example
sum += this -> v[i] * y . v[i];
would normally jusy be written as in this context
sum += v[i] * y . v[i];
I hope this is homework!
Otherwise you should be using std::Vector
Couple of problems:
A constructor should initialize all members.
Neither constructor does this.
The copy constructor (or what seems to be) is not defined incorrectly.
Because your class manages a RAW pointer you need to see "The rule of three"
ie you are missing the assignment operator
Prefer to use initializer lists when you can
In addition to all the correct answers here, consider adding keyword explicit before all your constructors that accept only one argument. That way it will never be confused with assignment operations. Here's another question that explains it.
vector (int *a)
{
for(int i=0; i<size; i++)
v[i] = a[i];
}
This constructor couldn't possibly work.
The v member is not initialized. You have not allocated storage for the values.
The size member is uninitialized. The loop will try to read an undeterminate amount of values from the passed pointer.
There is no way to initialize size. If you are given just an int*, there is no way to determine how large the pointed array is (if the pointer even points into an array in the first place). This is the reason, why the number of elements in the array has to be passed separately (and why plain arrays are a PITA).

C++ two dimensional arrays with pointers

I have a problem with two dimensional arrays :( I feel very stupid and Visual C does not help me :( and I also think that my mistake is very stupid but still I can't find it :( I have this code:
double matrix[100][100]; //which is full with a matrix 3x4
double nVector[10000]; // for negative doubles
//I wanted to see if there are negative doubles in each row and column
//and I want this to happen with function
And this is my function:
double* negativeVector(double*nVector, double*fromVector, int m, int n){
int position = 0;
double *myNegArray = nVector;
double *myMatrix = fromVector;
for(int i = 0; i < m*n; i++)
if(*(*(myMatrix+i)) < 0){
*(myNegArray+position) = *(*(myMatrix+i));
position++;
}
return myNegArray;
}
//for double*nVector I'm passing nVector
//for double*fromVector I'm passing *matrix
Visual C tells me that I have an error C2100: illegal indirection here: *(*(myMatrix+i)) I hope someone can help me (happy)
Thanks in advance!
*(*(myMatrix+i)) is wrong. This is a common mistake.
2D matrix does not create an array of pointers which you can access this way. It is a different structure. Even though an array is a pointer, 2D array is not a pointer to pointer, and it cannot be dereferrenced twice. Nor you have any other way to access element at coordinates (x,y) without knowing the layout in memory, because pointers to every line are nowhere to be found. For instance, char **argv parameter of main() is not a 2D array. This is an array of pointers to arrays, which is something else.
There're two ways to fix it.
One is replace
double *myMatrix = fromVector;
by
double *myMatrix[100] = (appropriate cast)fromVector;
and index it as myMatrix[i/n][i%n]
But then remember that 100 is a constant expression, and it cannot be passed as a parameter. Alternatively, you can implement the indexing operation yourself:
Pass additional parameter: matrix line size (100)
Instead of *(*(myMatrix+i)), write:
int row = i/n;
int col = i%n;
*(myMatrix+row*line_size+col) is your element.
first you might wanna start a small struct like
struct tmp {
bool negative;
double value;
};
and make your own way up to the
tmp *myvars [100][100];
.
instead try using that struct and try the std::vectors instead of arrays if that's possible then try using pointers on decalring the variable "1 time only" when declaring the variable as i said above
then pass arguments
( tmp *mystructpointer )
mystructpointer->.......
access your matrix directly ... peice of cake :D
If you are passing *matrix, you are actually passing a double[100] (an array of 100 doubles), that happens to be passed as a pointer to its first element. If you advance further than those 100 doubles using i added to that pointer, you advance into the next array of 100 doubles, since the 100 arrays of 100 doubles are stored next to each other.
Background: A multi-dimensional array is an array whose element type is itself an array. An array like double a[100][100]; can be declared equivalently as typedef double aT[100]; aT a[100];. If you use an array like a pointer, a temporary pointer is created to the array's first element (which might be an array). The * operator is such an operation, and doing *a creates a pointer of type double(*)[100] (which is a pointer to an array of 100 doubles), and dereferences it. So what you end up with *matrix is a double[100]. Passing it to the negativeVector function will create a pointer to its first element, which is of type double*.
Your pointer parameters point to the start of each of two arrays of 100 doubles each. So you should rewrite the function as
double* negativeVector(double*nVector, double*fromVector, int m, int n){
int position = 0;
double *myNegArray = nVector;
double *myMatrix = fromVector;
for(int i = 0; i < m*n; i++)
if(*(myMatrix + i) < 0){
*(myNegArray + position) = *(myMatrix + i);
position++;
}
return myNegArray;
}
Notice that since your i iterates beyond the first of the 100 arrays stored in the 2d array, you will formally not be correct with this. But as it happens those arrays must be allocated next to each other, it will work in practice (and in fact, is recommended as a good enough work around for passing multi-dimensional arrays around as pointers to their first scalar element).
I have no clue why you are copying the arrays twice (once in the parameters of the function and a second time by declaring some new arrays)... You should also think of using the STL... std::vector will make the your life way easier ;)
double* negativeVector(double*nVector, double*fromVector, int m, int n){
int position = 0;
double *myNegArray = nVector;
double *myMatrix = fromVector;
for(int i = 0; i < m*n; i++)
if(*((myMatrix+i)) < 0){
*(myNegArray+position) = *((myMatrix+i));
position++;
}
return myNegArray;
}
is that homework? some templates - just for fun ;-)
double matrix[100][100];
double nVector[10000];
template< const int m, const int n >
double* negativeVector( double* myNegArray, const double (&myMatrix)[m][n] )
{
int position = 0;
for( int i = 0; i < m; ++i )
{
for( int j = 0; j < n; ++j )
{
const double value = myMatrix[ i ][ j ];
if ( value < 0 )
{
myNegArray[ position ] = value;
++position;
}
}
}
return myNegArray;
}
int main()
{
//...initialize matrix here...
negativeVector( nVector, matrix );
}
Perhaps rewrite this using std::vector to increase readability? (#):
#include <vector>
std::vector< std::vector<double> > matrix; //which is full with a matrix 3x4
std::vector<double> row;
row.resize(100,0);
matrix.resize(100,row);
std::vector<double> nVector; // for negative doubles, no size, we'll "push_back"
//I wanted to see if there are negative doubles in each row and column
//and I want this to happen with function
This is the stl enabled version of the function:
//I'm returning void because nvector contains the result,
//so I don't feel the need to return anything. vectors contain their
//own size so n and m are also not needed. Alsom pass in references
void negativeVector(std::vector<double>& nVector,
std::vector< std::vector<double> >& fromVector){
nVector.clear();
int i,j;
for(i = 0; i < fromVector.size(); i++) {
for(j = 0; j < fromVector[i].size(); j++) {
if(fromVector[i][j] < 0){
nVector.push_back(fromVector[i][j]);
}
}
}
}
call with:
negativeVector(nVector, matrix);
Once the function completes, nVector contains all negative numbers in matrix.
Read more about std::vector here.
(#) for people like me who are too lazy/stupid to comprehend code containing pointers.
Take a look at C++ Faq site:
How do I allocate multidimensional arrays using new?
link
And read until point [16.20] summarize all the answers you are getting and at the end you get a very useful Matrix template class.
Have a good read.

Passing a variable of type int[5][5] to a function that requires int**

I'd like to test a function that takes runtime-allocated multidimensional arrays, by passing it a hardcoded array.
The function has a signature of void generate_all_paths(int** maze, int size) and the array is defined as int arr[5][5] = {REMOVED}.
I'm not exactly sure how to properly coerce the array for the function (or if that is impossible).
This multi dimensional array topic unfortunately confuses so many C++ programmers. Well, here is the solution:
void generate_all_paths(int (*maze)[5], int size);
That is what the function declaration has to look like. An alternative, but fully equivalent is
void generate_all_paths(int maze[][5], int size);
Both are creating a parameter that is a pointer to an array of 5 integers. You can then pass your array of arrays of 5 integers to that function:
generate_all_paths(arr, 5);
Because your array's first element is an array of 5 integers, it will be converted automatically (implicitly) to a pointer to that first element when passed to that function.
In the comments, you have shown you are bound to an int**, because both your inner and outer dimension must have runtime values. A multi-dimensional array can not be used anymore. What you can do for testing purposes then is to create an array of pointers like this:
int store[5 * 5] = { ..... };
int *arr[5] = { store, store + 5, store + 10, store + 15, store + 20 };
Then, actually, you can have your function accept a int**. As the first element of you array then is a int*, it will be converted to a int** automatically. Another way of doing this is keeping the data in the 2 dimensional array, but just creating a "view" structured of pointers to that array:
int *arr[5] = { store[0], store[1], store[2], store[3], store[4] };
Where store is your int[5][5] array. Since store[n] accesses the n'th sub-array of that two-dimensional array and the element type of it is int, the pointer-converted type of it is int*, which will be compatible again.
You can write:
void display(char **a)
And then use a[i][j] to refer to elements in it.
The declaration char ** means "pointer to pointer to integer". To break it down into steps:
char *b = a[i];
That gets you a pointer to the first element of the i'th array in the array-of-arrays.
char c = b[j];
That gets you the j'th element in the array b.
The next problem you'll have is of allocating such an array-of-arrays.
char **arrayOfArrays = new char *[10];
for (int n = 0; n < 10; n++)
arrayOfArrays[n] = new char[20];
That allocates an array of 10 arrays, each "child" array having 20 characters.
In C/C++, array access syntax is just a way of retrieving a value some distance away from a pointer.
char *p = "Hello";
char *pl = p + 2; // get pointer to middle 'l'
char l = *pl; // fetch
char o = p[4]; // use array syntax instead
void display(char ** array)
should work. Also I don't think that it is a reserved word in standard C/C++.
And also, why is array a reserved word?
It isn't. You are probably using Visual Studio where it's displayed as a keyword due to its use in C++/CLI as a native managed type. However, this is irrelevant for C++ and Visual Studio is misleading in that regard.
As to your problem: You can simply pass a pointer-to-pointers-to-char and then pass your nested array directly (provided you are working with a dynamically allocated array):
void display(char** array) …
That said, your function assumes a fixed, known array length and some other details. Better would be to use a nested std::vector, or std::string (for instance). Using such existing data types makes your life much easier.
void display(std::vector<std::string> const& array) {
for (size_t i = 0; i < array.length(); ++i)
cout << array[i] << endl;
}
To take advantage of this, your calling code needs to be changed as well to use these data structures instead of plain C arrays on chars.
The Earwicker's answer is missing an important fact. What he is proposing is an array of arrays. For the first this wastes memory for the array of pointers ("char **arrayOfArrays = new char *[10]" is the creation point of this). For the second the array of chars may then not be a continuous block of memory, which is often a problem.
The only workaround in C++ is to create a one dimensional array and calculate the indexes when you need them.
char *b = new char[width*height];
then you can refer to element x,y (x is along width, y along height) like this
char c=b[width*y+x];
This may be however a bit slower than the solution above (measured on GCC 3.4.5), so if you are not interested in continuous memory (for example you always access the elements with [][], never by adding integer to a pointer and dereferencing it), then you should use the array af arrays. However, if you are interested in having the continuous memory, e.g. to pass it as initializer to an std::string object or to send it as a whole through a network, you should use the second one.
The best is to use pointers, but Borland C++ admits passing arrays as parameters for functions. Look at this code (includes: iostream and conio):
////////////////////////////////////////////
void ReceivedArray(char x[5]){
for (int i=0; i<5; i++ )
cout << x[i];
}
void main(){
char *x = new char[5];
for (int i=0; i<5; i++ )
x[i]='o';
ReceivedArray(x);
getchar();
}
///////////////////////////////////////////////////////////////
For passing 2D arrays (oops! some lines in spanish, sorry!):
(includes: iostream, stdlb, stdio and math)
/////////////////////////////////////////////////
using namespace std;
void ver(int x[][20]){
for(int i=0; i<15; i++) {
for(int j=0; j<20; j++) {
cout<< x[i][j] <<" "; }
cout << "\n"; }
}
void cambiar0(int x[][20]){ int n[255];
for (int i=255; i>=0; i--)
n[255-i]=i;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
for(int k=0; k<255; k++)
if(x[i][j]==n[k]) {
x[i][j]=k; break; }
}
int main(int argc, char* argv[]){
int x[15][20]; char a;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
x[i][j]=rand()%255;
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
cambiar0(x);
cout << "\n\n";
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
system("PAUSE"); return 0;
}
///////////////////////////////////
Hope this is what you meant.
arr is a pointer to the multi-dimesional array you have and is actually a pointer to an int. Now since your function accepts a pointer to an int pointer, you need to get the address of arr using: &arr and pass that to the function so that you will have this code:
To coerce the array: Pass &arr to the function.
To reference the array inside the func: *maze[x][y]