pushing back a class object into a vector - c++

I have a vector that takes in a class object but when I try to push back the object I have created into the vector I am getting these problems and don't know how to getnaround it. Can anyone help me please ?
void populate( std::vector<NV*> vNav, NV *nVess);
creating the object class
NV vPB;
object class variables matching up
vPB.name = namE;
vPB.type = typE;
vPB.length = lengtH;
vPB.speed = speeD;
vPB.range = rangE;
vPB.serialNum = serialNuM;
vPB.serialNum = beaM;
vPB.displacement = displacemenT;
vPB.draft = drafT;
vPB.isActive = isActivE;
namE = name;
typE = type;
lengtH = length;
speeD = speed;
rangE = range;
serialNuM = serialNum;
beaM = beam;
displacemenT = displacement;
drafT = draft;
isActivE = isActive;
vNav.push_back(vPB);
keep getting error error C2664: cannot convert parameter 1 from 'N_V::NV' to 'N_V::NV *&&'
and also keep getting error IntelliSence no instance of overload function

The vector is expecting a pointer to an object whereas the vPB you are pushing back is not a pointer to an object but rather the object itself.
The minimum you can do to fix this is:
NV* vPB = new NV();
vPB->name = namE;
... and similarly for all the members you need to initialize ...
vNav.push_back(vPB);
Secondly the vNav vector is only going to exist within the context of that function because it is being passed by value. You probably want to take the argument by reference. This means changing your function's signature to:
void populate( std::vector<NV*>& vNav, NV *nVess);
Lastly it's not advisable to use naked pointers if you can help it. Try looking into shared_ptr and unique_ptr as a more advanced step to ensure that the object's lifetime is correctly managed and you don't leak memory allocations.

vNav is declared as std::vector<NV*>, but you try to push a NV type into there, an object not a pointer. So it's a type mismatch. You also pass the vector by value, which is probably not intended.
Using vector of pointers will be quite problematic. Because you need to manually allocate space for objects and then remember to allocate them. I would advise to revise the code to use std::vector<NV> or at least read about smart pointers.

As others pointed out, you are trying to insert an object where the type should be object pointer. Another error is you are passing the vector by value, it should be by reference, otherwise the caller will not see the effect of insertion.
void populate( std::vector<NV*>& vNav, NV *nVess);

I would write your populate function as
void populate( std::vector<NV>& vNav, NV& nVess);
unless you want to add pointers to the objects inside the vector.
And it is not clear where you get this error. Can you post the code where you get the error? Is it in push_back? If yes, then it's because you are trying to push back an object but your vector expects a pointer to object.

Related

cannot assign to array of pointers in c++

I need to keep an array of pointers in c++. I have a Set which keeps objects of my class. Then I need to iterate over the set and keep the pointer of each item in array. array is 2D by the way. so What I need in summary is :
pointers[1][4] = PinterToAnItem; the reason is I need to delete the item later, So I want to keep the pointer and directly go to that and delete it, instead of iterate again and find and then delete. But I have an error in assigning the array. I dont know how this idea will work, but so far it gives me error. Please let me know if it is not clear
the error is : " a value of type CONST Movie cannot be assigned to type of Movie"
struct Movie
{
int movieId;
int shopId;
int priceId;
};
Movie *pointers[100][100];
set<Movie> setMovie;
void main()
{
//reading and initialize the set with movies
// for example movie1 = {0,10,3} so I want to keep in my array a pointer to this object as:
// pointer [0][10] = ObjectPointer
// I have error in loop body. Also (*id), id and &id does not work.
for (auto id = setMovie.begin(); id != setMovie.end(); id++)
pointers[(*id).movieId][(*id).shopId] = &(*id);
}
2- by the way, do you guys think it is a fine Idea? can I delete pointer[0][10] which points to an object in my set? so by this way I don't need to iterate again through the set and delete (0,10). I have a pointer to (0,10) and I erase it from the set.
Thanks
EDITED
The answer from #Jeffry is right but it does not work for rest of my problem which is erasing the specified item. i intended to keep a pointer to an item and then erase it directly. But we know set.erase(ITERATOR) or (actual_value). so pointer here does not work for me. I had to change array of iterators, then it works. So I completed here maybe works for some later.
set<Movie> ::iterator pointers[100][100];
for (auto id = setMovie.begin(); id != setMovie.end(); id++)
pointers[(*id).movieId][(*id).shopId] = id; // I changed here as well
setMovie[1].erase(pointers[1][0]); // works well
// pointers[1][0] is an iterator to an item in set with movieid=1,shopid=0
pointers[(*id).movieId][(*id).shopId] = &(*id);
tries to store in pointers a pointer to a Movie, pointing into the setMovie.
Now consider what happens, after you do this. What if you did:
pointers[42][43]->priceId = 44;
That would possibly invalidate the set (you could have twice the same Movie). That is why the set doesn't let you do it.
One way around is:
const Movie *pointers[100][100];
Then, you could store the pointer because you wouldn't legally be allowed to modify movies, and mess up the ordering. I'm not sure that makes it a good idea, but it would solve your immediate problem.
For 2, no, it would not be a good idea to call delete on a pointer pointing to a movie stored in your set. You did not call new on this object, so you should not delete it. If you try, you'll get a crash immediately, or much later.

Pointer to array - initialize element

I have a class Pixel and a class Image with a function used to update a pixel line. I want to initialize the pixel line. My problem is to initialize the array. Actually I have this :
bool UpdateLine(Pixel line[], int nb)
{
bool noError = true;
line = new Pixel[nb];
for (int r = 0; r < nb; r++)
{
line[r] = new Pixel(); // -> line causing troubles
// do some stuff with my pixel
[...]
}
return noError;
}
When I try this I have :
no viable overloaded '='
How can I initialize each elements for my array ?
You actually have two problems.
The first, regarding your error, is because new Pixel() results in a pointer to a Pixel object. In C++ you don't need new to create objects (do you come from a Java or C# background perhaps?). The initial allocation of the array creates the objects for you.
The second problem is that you assign to the pointer variable line, but line is a local variable inside the function. All modification to it will be lost once the function returns, and you will have a memory leak. You need to pass line by reference.
In the future when dealing with collections of a single type of data, I suggest you use std::vector instead. You still need to pass the vector by reference though, if you want to add elements to it.
line[r] = new Pixel(); // -> line causing troubles
line[r] is a Pixel object, not a pointer, so you can't assign a pointer to it.
Why aren't you using a std::vector?

How to delete pointers from vector pointer

I use bison parser generator that has union type for return type productions.
union {
std::vector<std::string*> *vecStrPtr;
// double num; ...
};
how delete pointer from vector pointer;
auto v = new std::vector<std::string*>();
//....
v->push_back(new std::string("text"));
//...
delete v[0];
error: type 'class std::vector<std::__cxx11::basic_string<char>*>' argument given to 'delete', expected pointer delete v[0];
When you do just v[0] you get the vector because v is a pointer and then you need to get value from that vector. You can do it by adding another array access. So working code would look like delete v[0][0];. But two array accesses can be confusing when you are accessing value from one dimension array (vector).
Another way to get vector from pointer v is to dereference it. Code would look like (*v)[0]. It's more clear accessing the value. With (*v) you will get the vector and then the array access is to access the value from vector.
To remove value from vector use method erase. For more information about that method look at this link. Code example would look like:
auto v = new std::vector<std::string*>();
//....
v->push_back(new std::string("text"));
//...
delete (*v)[0];
v->erase(v->begin());
Better is to write code without keyword new. With that rule you will get less memory leaks. It makes your developing easier. But in some cases you can't use it. Your code example modified by that rule would look like:
std::vector<std::string> v;
v.push_back(std::string("text"));
//here is how to get pointers from it
std::string* ptrToElement = &(v[0]);
std::vector<std::string>* ptrToVector = &v;
The right way to free one item is:
delete (*v)[index];
v->erase(b->begin()+index);
However, You should make sure that you really want to allocate a vector in the free store. It seems usually so wrong.
P.S. As #Dahn mentioned, Those two instructions should be atomic.

Vector overwriting object pointers

Everytime I call this method, The information is overwritten. If I call this function with name = "greg" then it will cout greg, If I then input "carl" it will cout carlcarl. The constructor is empty, and group and _groups are declared in the header.
I've been stuck on this for about 6 hours and I'm at a loss. Can someone explain to me how to fix this? It's not shown, but "group" is an object pointer. I'm taking this as a college course and its pretty much self-taught, I have to follow strict instructions on what to use and what not to use. I can't use strings.
void GroupDB::addGroup(char* name)
{
group = new GroupInfo(name, _nextGid++);
_groups.push_back(group);
for(int i = 0; i < _size; i++)
{
cout << (*_groups.at(i)).getGroupName();
}
_size++;
}
It sound's like you're storing the name pointer itself, which points to a temporary array that's invalidated at some point after this function returns. Instead, you want to store a more persistent copy of the string data. Use std::string not char* to store strings. If you "can't use strings" as a condition of the exercise, then you'll need to allocate an array to store the string data in, just as std::string would.
In general, don't use pointers unless you really need to. I doubt you want to be messing around with new here, but should rather store GroupInfo objects directly in the vector (or whatever _groups is).

How to access a vector through a pointer?

I want to insert new element into a vector using a pointer I have the following sample code:
struct info {
string Name;
int places; // i will use the binary value to identfy the visited places example 29 is 100101
// this means he visited three places (London,LA,Rome)
vector<int> times; // will represent the visiting time,e.g. 1,2,5 means london 1 time, LA
// twice and Rome five times
};
map<string,vector<info> *> log;
Peaple are coming from different cities, I will check if the city exists, just add the new person to the vector, else creat a new map object:
vector<info> tp;
info tmp;
if(log.size()==0|| log.count(city)==0) //empty or not exist
{
tp.push_back(tmp);
vector<info>* ss = new vector<info>;
ss=&(tp);
// create a new object
log.insert(map<string,vector<info> * >::value_type(city,ss)); // new object
}
else // city exist, just add the information to the vector
{
map<string,vector<info> *>::iterator t;
t=log.find(city);
*(t->second).push_back(tmp); //the problem in this line
}
How can I insert the new tmp into the vector?
The information to be read as follows:
Paris,Juli,5,3,6
Paris,John,24,2
Canberra,John,4,3
London,Mary,29,4,1,2
There are a lot of mistakes here, and they all stem from misusing pointers. The line that is mentioned as the cause of the problem is a minor syntactic issue. There are bigger issues at hand.
All of them can be easily solved by not misusing pointers. There is no reason to use pointers here, so the ultimate fix is to make the map have this type map<string,vector<info>> log;.
Then the code becomes something like this:
info tmp;
log[city].push_back(tmp);
// the [] operator creates a new empty vector if it doesn't exist yet
// there's no point in doing the checks by hand
Now that we have a simple solution, I'll mention the elephant in the room code.
vector<info>* ss = new vector<info>;
ss=&(tp);
// ...
log.insert(map<string,vector<info> * >::value_type(city,ss));
This sequence of operations will create a vector with dynamic storage duration, and immediately discard the sole pointer to it. That causes the vector that was just created to be lost, and the memory it uses is leaked; it cannot be recovered anymore.
To make matters worse, it sets ss to point to a local variable, and then saves that pointer to the local variable in the map. Because the local variable has automatic storage duration, it is gone once the function returns. That makes the pointer that was just stored in the map invalid, because it no longer has a vector to point to. After that, all kinds of havoc would be wreaked.
Looks like you need to do like this
(t->second)->push_back(tmp);