Invalid conversion from int* to int even though I delimit the pointer - c++

I've received the following error:
NQueens.cpp:35:19: error: invalid conversion from 'int*' to 'int' [-fpermissive]
solution[i].y = *(possibilities + i);
I believe I delimited the pointer so that I can apply the value being pointed to the y coordinate for the n-queens problem. Am I missing anything, or is my compiler being dumb?
My header file:
#pragma once
#ifndef QUEEN
#define QUEEN
struct Queen {
int x, y;
};
#endif // !QUEEN
My C++ code:
#include "Queen.h"
#include <iostream>
#include <vector>
using namespace std;
bool isDiag(int, int, int, int);
bool solutionFinder(int, int, vector<int*>);
int main()
{
int n;
cout << "Enter a number n for the n-queen problem:\n";
cin >> n;
vector<int*> possibilities;
for (int i = 0; i < n; i++)
{
int arrayInt[n];
arrayInt[0] = i + 1;
for (int j = 1; j < n; j++)
{
arrayInt[j] = 0;
}
possibilities.push_back(arrayInt);
}
if (!solutionFinder(1, n, possibilities))
{
cout << "No Solution.\n";
}
Queen solution[n];
for (int i = 0; i < n; i++)
{
solution[i].x = i + 1;
solution[i].y = *(possibilities.begin() + i);
}
cout << "Solution: [(" << solution[0].x << "," << solution[0].y << ")";
for (int i = 1; i < n; i++)
cout << ", (" << solution[i].x << "," << solution[i].y << ")";
cout << "]\n";
return 0;
}
UPDATE:
I've tried the fix that mch suggested and now it compiles fine. However, I've ran into a new problem. When trying to print the coordinates for the queens, I'm getting what I believe are the locations of the values in memory.
Example:
Enter a number n for the n-queen problem:
4
Solution: [(1,1163548928), (2,32764), (3,1163548704), (4,32764)]

There are multiple issues with this code, but your immediate problem stems from this:
vector<int*> possibilities;
...
for (...)
{
int arrayInt[n];
...
possibilities.push_back(arrayInt);
}
...
solution[i].y = *(possibilities.begin() + i);
You have a vector of int* pointers, which are pointing at int[] arrays which you are creating inside a loop (and will be destroyed at the end of each loop iteration, thus leaving the vector holding dangling pointers to invalid memory).
You are then iterating through the vector, extracting each int* pointer and trying to assign it as-is to a single int, thus the compiler error. You would need to instead dereference the int* to get individual int values from the array, eg:
int *arr = *(possibilities.begin() + i);
solution[i].y = arr[someIndex];
Based on what you have shown, I think you have implemented your solutionFinder() incorrectly (but you didn't show how you actually implemented it). Rather than outputting a vector of int[] arrays, it would be better to have it output a vector of Queens instead, eg:
#include "Queen.h"
#include <iostream>
#include <vector>
using namespace std;
bool isDiag(int, int, int, int);
bool solutionFinder(int, int, vector<Queen>&);
int main()
{
int n;
cout << "Enter a number n for the n-queen problem:\n";
cin >> n;
vector<Queen> solution;
solution.reserve(n);
if (!solutionFinder(1, n, solution))
{
cout << "No Solution.\n";
return 0;
}
cout << "Solution: [(" << solution[0].x << "," << solution[0].y << ")";
for (int i = 1; i < n; ++i)
cout << ", (" << solution[i].x << "," << solution[i].y << ")";
cout << "]\n";
return 0;
}
bool isDiag(int, int, int, int)
{
// ...
}
bool solutionFinder(int, int, vector<Queen> &solution)
{
// populate solution with Queen's as needed...
for (...)
{
Queen q;
q.x = ...;
q.y = ...;
solution.push_back(q);
}
...
}

Contrary to the various comments you /can/ do can do arithmetic on "random access" iterators.
The issue is that you declared you have a vector of pointers.
You access the iterator like a pointer using operator * to indirect, but then you would would need to indirect again (another *) to follow the pointer held in the cell of the vector.
It is simper to use the array index syntax with vector poss[i] rather than *(poss.begin()+i) but you still need to do that extra indirection if you do indeed have a vector of pointers, *(poss[i]) which looks a bit ugly.

Related

Why is this code accessing vector out of its range?

So, I'm trying bring over some code to a Qt project I'm working on. The Motion class imports some control points from .txt file into the public member variable ctrlPos using fstream. When I use readCtrlPositions and then try to access ctrlPos with writePositions, for example, I get the error "vector subscript out of range".
There is a lot more code, but hopefully this should be sufficient to answer my question. I'm also a bit of a novice, so with any luck it's not something too stupid.
Motion class header:
#ifndef MOTION_H
#define MOTION_H
#include <vector>
#include "DualQuaternion.h"
class Motion
{
public:
virtual ~Motion();
virtual void readCtrlPositions(char*, char*);
virtual void writePositions(char*);
virtual void drawCtrlPositions();
virtual void set(int, vector<DualQuaternion>);
virtual pair<int, vector<DualQuaternion>> get();
public:
vector<DualQuaternion> ctrlPos, c;
int numberOfPositions;
};
#endif
Motion class:
#include <stdlib.h>
#include <GL\glut.h>
#include "motion.h"
#include "Quaternion.h"
#include "hMatrix.h"
#include "hPoint.h"
using namespace std;
void Motion::readCtrlPositions(char *fileNameArg, char *t)
{
ifstream inFile(fileNameArg, ios::in);
if (!inFile)
{
cerr<<"File" << fileNameArg << "could not be opened" << endl;
exit(1);
}
int i;
inFile >> numberOfPositions;
Quaternion *RotationQuaternion = new Quaternion[numberOfPositions];
for (i = 0; i<numberOfPositions; i++)
inFile >> RotationQuaternion[i];
if (t == "v")
{
Vector *TranslationVector = new Vector[numberOfPositions];
for (i = 0; i<numberOfPositions; i++)
inFile >> TranslationVector[i];
ctrlPos.clear();
for (i = 0; i<numberOfPositions; i++)
{
DualQuaternion dQ(RotationQuaternion[i], TranslationVector[i]);
ctrlPos.push_back(dQ);
cout << "first position from input: " << ctrlPos[i] << endl;
}
delete[] TranslationVector;
}
else if (t == "q")
{
Quaternion *TranslationQuaternion = new Quaternion[numberOfPositions];
for (i = 0; i<numberOfPositions; i++)
inFile >> TranslationQuaternion[i];
ctrlPos.clear();
for (i = 0; i<numberOfPositions; i++)
{
DualQuaternion dQ(RotationQuaternion[i], TranslationQuaternion[i]);
ctrlPos.push_back(dQ);
cout << "first position from input: " << ctrlPos[i] << endl;
}
delete[] TranslationQuaternion;
}
delete[] RotationQuaternion;
}
void Motion::writePositions(char *fileNameArg)
{
ofstream outFile(fileNameArg, ios::out);
if (!outFile)
{
cerr<<"File" << fileNameArg << "could not be opened for writing" << endl;
exit(1);
}
int i;
outFile << numberOfPositions << endl << endl;
for (i = 0; i<numberOfPositions; i++)
outFile << ctrlPos[i].GetReal();
outFile << endl;
for (i = 0; i<numberOfPositions; i++)
outFile << ctrlPos[i].GetDual();
}
void Motion::set(int n, vector<DualQuaternion> p)
{
int i;
numberOfPositions = n;
ctrlPos.clear();
for (i = 0; i<numberOfPositions; i++)
ctrlPos.push_back(p[i]);
}
pair<int, vector<DualQuaternion>> Motion::get()
{
return make_pair(numberOfPositions, ctrlPos);
}
void Motion::drawCtrlPositions()
{
vector <hMatrix> homogeneousMatricesForCtrlPositions;
for (int i=0; i<numberOfPositions; i++)
{
homogeneousMatricesForCtrlPositions.push_back(ctrlPos[i].dualQuaternionToHomogeneousMatrix().transpose());
double MatrixforOpenGLStack[16];
for (int i1=0; i1<4; i1++)
for (int i2=0; i2<4; i2++)
MatrixforOpenGLStack[4*i1+i2] = homogeneousMatricesForCtrlPositions.at(i).m[i1][i2];
::glPushMatrix();
::glMultMatrixd(MatrixforOpenGLStack);
glutSolidTeapot(0.15);
::glPopMatrix();
}
}
Motion::~Motion()
{
}
Sample code where error occurs in Qt program:
static Curve m;
m.readCtrlPositions("input.txt", "v");
m.writePositions("output.txt"); //<--vector subscript out of range
m.readCtrlPositions("output.txt", "q");
ctrlPos = m.get().second;
numberOfPositions = m.get().first;
In readCtrlPositions, t is a char*, so nor t=="v", nor t=="q" will be evaluated to true (it would return true if the two pointers were having the same address). So your function will set numberOfPositions to a non zero value but will never fill ctrlPos vector with any value.
Later, you'll try to access ctrlPos elements from 0 to numberOfPositions (not zero), while ctrlPos vector is empty. That's why you are reported to access the vector out of its range!
Replace char* by std::string is an easy way to fix the problem. If you need to keep the parameter as a char*, then use strcmp to compare string values rather than pointers.
I would also strongly recommend that you remove your numberOfPositions attribute and simply use ctrlPos.size() instead. It would have prevented a crash in this case by guaranteeing your class attributes integrity.

Novice C++, seeking help in array division

#include <iostream>
#include <valarray>
using namespace std;
// to get new card number
int main ()
{
int i;
int array[5]= {10,2,6,34,51};
valarray<int> v[5];
int v %= 13;
for (int i=0; i<5 ; i++) {
cout << v[i]%=13 << " ";
}
}
hello, my goal is to get the array to perform a modulus division by number 13.
I've search and try a few different way but I can't figure out a way to make it work.....
Thank you...
Some of the problems with your code:
valarray does not have the same notation as normal arrays: valarray<int> v[5]; declares 5 different valarray objects and puts them in a C-style array. The notation you are looking for is valarray<int> v(10);
Get rid of the int v %= 13; line: this redefines v (an array) as an integer.
Use v[i]=(array[i]%13); for the calculation, what you have doesn't make sense.
Then output cout << v[i] << " ";
Also, you aren't really using any of the features of valarray, so it may make more sense just to use one single array, like:
#include <iostream>
using namespace std;
// to get new card number
int main ()
{
int array[5]= {10,2,6,34,51};
for (int i=0; i<5 ; i++) {
array[i]%=13;
cout << array[i] << " ";
}
}
Edit: by the way, the cool thing about valarray here is that you can apply the same function to every value at once. Like this:
#include <iostream>
#include <valarray>
using namespace std;
int main() {
valarray<int> v(10);
for (int i=0;i<10;++i) {
v[i]=i*i; //Fill the array with 0,1,4,9,16,... as an example
}
v%=13; //This applies the modulo 13 on the whole array at once.
for (int i=0;i<10;++i) {
cout << v[i] << endl;
}
}
Seems you want something like...
int array[5]= {10,2,6,34,51};
int v[5];
for (int i = 0; i < 5; ++i)
v[i] = array[i] % 13;
for (int i = 0; i < 5; ++i)
std::cout << v[i] << " ";
std::cout << '\n';

Error must have class type

I'm kinda new in C++ and when trying to compile this code I get and error that I do not know how to fix:
int main()
{
typedef pair<int,int> nodo;
int x;
cin >> x;
int *g;
g = new int[x];
vector <nodo> g;
g[1].push_back(nodo(2,5));
g[1].push_back(nodo(3,10));
g[3].push_back(nodo(2,12));
g[2].push_back(nodo(4,1));
g[4].push_back(nodo(3,2));
for (int i = 1; i <=4; ++i){
// cout << i << " -> ";
for (int j = 0; j<g[i].size(); ++j){
// cout << g[i][j].first << " c: " << g[i][j].second << " ";
}
// cout << endl;
}
dijkstra(1, x);
system("pause");
return 0;
}
The error I am receiving is:
Error: Expression must have a class type.
Here:
int *g;
g = new int[x];
vector <nodo> g; // ERROR: Redeclaration!
You are first declaring g to be of type int*, and then you re-declare it to be of type vector<nodo>. This is illegal.
Moreover, you need to have a using namespace std directive if you want to omit the std:: qualification for types in the standard namespace. I do not suggest you using that though. Much better explicitly specifying std::, or rather use specific using declarations.
For instance:
typedef std::pair<int,int> nodo;
// ^^^^^
int x;
std::cin >> x;
// ^^^^^
int *g;
g = new int[x];
std::vector <nodo> g;
// ^^^^^
Also make sure you are importing all the necessary standard headers:
Type | Header
--------------------------
std::vector -> <vector>
std::pair -> <utility>
std::cin -> <iostream>
You're redeclaring g, first it's an int* and then you make it into a vector<int>. I'm not sure how that got past the compiler.
Also, rather than using nodo(1,2) consider using make_pair instead. Using new is also considered bad practice and you should use either a dynamic container like std::vector or a static one like std::array.
You have two things named g:
int* g;
and
vector <nodo> g;
This wouldn't even compile.
It looks like you want an array of vectors, in which case you need something like
std::vector<std::vector<nodo> > g(x); // size x vector of vectors.
Then you can do this type of thing:
g[1].push_back(nodo(2,5));
g[1].push_back(nodo(3,10));
pair is not a class because you haven't included <utility>
You also haven't included <vector> or <iostream>.
So this version compiles and I think this is what you meant to do:
// Need to include these headers
#include <utility>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
typedef pair<int,int> nodo;
int x;
cin >> x;
//int *h;
//h = new int[x];
//specify size of vector
std::vector< std::vector<nodo> > g(x);
g[0].push_back(nodo(2,5));
g[1].push_back(nodo(3,10));
g[2].push_back(nodo(2,12));
g[3].push_back(nodo(4,1));
g[4].push_back(nodo(3,2));
for (int i = 0; i < g.size(); ++i){
std::cout << i << " -> ";
for (int j = 0; j<g[i].size(); ++j){
cout << g[i][j].first << " c: " << g[i][j].second << " ";
}
cout << endl;
}
//dijkstra(1, x);
//system("pause");
return 0;
}
Many issues, you use g twice for one. I am not sure what you want to do with the vector but maybe you want a vector of vectors which would be more like this:
std::vector< std::vector<nodo> > g(x) ;
Then this would make more sense:
g[0].push_back(nodo(2,5)) ;
The first element of a vector is going to be at 0 not 1.

c++ references array

I wounder how i can make this code work?
#include <iostream>
using namespace std;
void writeTable(int (&tab)[],int x){
for(int i=0;i<x;i++){
cout << "Enter value " << i+1 <<endl;
cin >> tab[i] ;
}
}
int main(void){
int howMany;
cout << "How many elemets" << endl;
cin >> howMany;
int table[howMany];
int (&ref)[howMany]=table;
writeTable(ref,howMany);
return 0;
}
And here are the errors that I have:
|4|error: parameter ‘tab’ includes reference to array of unknown bound ‘int []’|
|18|error: invalid initialization of reference of type ‘int (&)[]’ from expression of type ‘int [(((unsigned int)(((int)howMany) + -0x00000000000000001)) + 1)]’|
|4|error: in passing argument 1 of ‘void writeTable(int (&)[], int)’|
Thanks for help
If you are intending to pass the size of the array, then remove the reference
void f(int a[])
is equivalent to
void f(int* a)
so no copying will be done, if that is the concern.
If you want to take an array by reference, then you MUST specify the dimension. e.g.
void f(int (&a)[10])
Naturally, the best of the two is the third solution, which is to use std::vector's and pass them by reference, reference to const or by value if needed. HTH
Here is a slightly more C++ style of doing it:
#include <iostream>
#include <vector>
void writeTable(std::vector<int> &tab)
{
int val;
for (unsigned int i=0; i<tab.size(); i++)
{
std::cout << "Enter value " << i+1 << std::endl;
if (std::cin >> val)
{
tab[i] = val;
}
}
}
int main()
{
int howMany;
std::cout << "How many elements?" << std::endl;
std::cin >> howMany;
std::vector<int> table(howMany);
writeTable(table);
return 0;
}
You need not specify the dimension of the array if you make writeTable a function template.
template <typename T,size_t N>
void writeTable(T (&tab)[N]) //Template argument deduction
{
for(int i=0 ; i<N ; i++){
// code ....
}
}
.
int table[howMany]; // C++ doesn't have Variable Length Arrays. `howMany` must be a constant
writeTable(table); // type and size of `table` is automatically deduced
Following Amardeep's answer, here is a C++11 way to do it:
#include <iostream>
#include <vector>
void writeTable(std::vector<int> &tab)
{
int val;
for (auto& cell : tab)
{
std::cout << "Enter value " << i+1 << std::endl;
if (std::cin >> val)
{
cell = val;
}
}
}
int main()
{
int howMany;
std::cout << "How many elements?" << std::endl;
std::cin >> howMany;
std::vector<int> table(howMany);
writeTable(table);
return 0;
}
Note the range-based for used in writeTable.
Arrays of references are illegal, if that is what you are trying to do. It's not 100% clear to me from the title.

Error in using vector pointer in a function

I have this code, but it won't compile and i can't understand what is wrong - i guess the pointering of the vector is not correct.
My idea was to collect some numbers in main() and store them in a vector and array, and then pass the memory address of them to a function, and using a pointers to print the data stored.
I came up with this when i read something about pointers which said that i should use them in order to save memory, so IMO the code below will not copy the contents of the vector and the array but use a pointer to access their location in memory - that's what i want to do.
#include <iostream>
#include <vector>
using namespace std;
void function(vector<int>* a, int *s)
{
cout << "function starts.." << endl;
for(int i=0;i<a->size();i++)
{
cout << a[i] << endl;
cout << s[a[i]] << endl;
}
cout << "function ends..." << endl;
}
int main(void)
{
vector<int> m;
int s[102];
for(int i=0;i<10;i++)
{
m.push_back(i*i);
s[i*i] = i-2;
}
function(&m, &s);
return 0;
}
I receive several errors on compiling, something is wrong.
Please tell me what's wrong with my code and how to fix it. thank you...
You should pass the vector by reference, not by pointer:
void function(vector<int>& a, int *s)
And then
function(m, ...);
Using [] on a pointer to a vector would certainly cause strange problems because it behaves as if a pointed to an array of std::vectors (while it actually only points to one). The vectors itself are never indexed by that. You could also use (*a)[...] to index the vector by the pointer.
if you insist in parsing by pointer then the correct syntax shoulld be:
void function(vector<int>* a, int *s[])
{
cout << "function starts.." << endl;
for(int i=0;i<a->size();i++)
{
cout << (*a)[i] << endl;
cout << (*s)[(*a)[i]] << endl;
}
cout << "function ends..." << endl;
}
First of all in the main program s is a pointer to an int, while m is a vector. Thus the function call should be as follows:
function(&m, s);
Secondly in the function a is a pointer to a vector, so should be indexed as follows: (*a)[i].
However you should really be using const references to pass your vector around:
void function(const vector& a, int *s)
{
..
cout << a[i] << endl;
..
}
And call it like:
function(m, s);
(corrected)
&s is in fact int(*)[102]: pointer to a pointer to an array of 102 items.
You should just say
function(&m, s);
This is because by old C legacy rule, an array is essentially a const pointer to its item with index 0. So s is already int*
This version works:
#include <iostream>
#include <vector>
using namespace std;
void function(const vector<int>& a, int s [102])
{
cout << "function starts.." << endl;
for(int i=0;i<(int)a.size();i++)
{
cout << a [i] << endl;
cout << s[a [i]] << endl;
}
cout << "function ends..." << endl;
}
int main(void)
{
vector<int> m;
int s[102];
for(int i=0;i<10;i++)
{
m.push_back(i*i);
s[i*i] = i-2;
}
function(m, s);
return 0;
}