C++ Adding new pointer objects to List - c++

I have a data structure defined up here called this:
typedef list <classSpec*> ClassSpecList;
I'm trying to add stuff into the list here based on functions that return certain values of that match the same data type. In one function, I have a list pointer object defined here and I have another statement that calls a function.
ClassSpecList *answer = 0;
classSpec *thisanswer = parseClass(br);
Basically I'm trying to add the results of what thisanswer returns into my main ClassSpecList. Problem is, when I try
answer->push_back(new classSpec (*thisanswer));
It compiles but I get a seg fault
When I try somethign else like:
answer->insert(ClassSpecList.begin(), *thisanswer);
I keep getting primary expression errors and I do not know why. I even tried it with other list made without typedef and I still get those.
Thank you.

You should initialize the pointer answer first, like :
ClassSpecList *answer = new ClassSpecList;
then you can add thisAnswer into this list.

This should work:
ClassSpecList *answer = new ClassSpecList;
answer->push_back(thisAnswer);
as should this, which is usually recommended:
ClassSpecList answer;
answer.push_back(thisAnswer);
If possible, parseClass shouldn't return a pointer, and you should use typedef list <classSpec> ClassSpecList;.

Related

Deleting and Reassigning a pointer from QList<Object *> to new Object using Iterator, is this right?

I have a QList and I'm trying to replace the objects in the list with new objects. The context is that I have a list of custom objects (the class name is "Conversation") to represent a list of group chats in a messaging platform. I use std::find_if to iterate through the list of pointers to find one with the right ID, and I want to take the pointer to that found object, deallocate it (delete?), and reassign that pointer to point at an object I generate with the "new" keyword. I think I'm doing this right but I'm not sure how to verify.
I tried a couple different iterations, ran into some issues where I realized I was using a const_iterator rather than just an iterator, so I couldn't modify any data. But I've fixed that and it seems like it's working, but I'm not positive.
Here's what I've got:
GroupChat *gc = new GroupChat(); // extends Conversation
// ...I update the member data here...
auto foundChat = std::find_if(conversations_.Conversations.begin2(),
conversations_.Conversations.end2(),
[this, gc](Conversation* o) { // my code to find the correct one...
}
if (foundChat != conversations_.Conversations.end()) {
auto c = (*foundChat);
delete c; // Is this right? Not positive...
//*foundChat = nullptr; // do I need this?
c = gc;
}
It seems like it's working but I'm worried about dangling pointers and incorrect memory deallocation/allocation. Could someone spot check me on this? Thanks for any help!

Warning removing dynamically created structs from QList of structs

I am writing q Qt5/C++ program with the following types:
struct SSensorScore {
Types::EScoreComparisons comparisonType;
ESensorValueTypes comparisonValueType;
QVariant comparisonValue;
};
typedef QList<SSensorScore> TSensorScoreList;
TSensorScoreList scoreList;
I append items to my scoreList list this:
SSensorScore *newScore = new Types::SSensorScore;
newScore->comparisonType = comparisonType;
newScore->comparisonValueType = Types::ESensorValueTypeUnknown;
newScore->comparisonValue = QVariant(config_score);
scoreList.append(*newScore);
and I remove them like this:
foreach (Types::SSensorScore score, scoreList) delete &score;
Is there something wrong with doing the above? When compiling the last line (delete the struct) gives me an error that 'the address of score will never be null'. So what? I must be missing the point of the warning...
Perhaps I'm confused about how to create a QList of dynamically created structs. Do I need to change my QList to a list of pointers? Do I need to cast my score so that delete knows it's dynamically created?
You have memory leak and undefine behaviour! :
scoreList.append(*newScore);
this line is going to copy the *newScore and then append it to scoreList. so you will leak newScore.
and this line :
foreach (Types::SSensorScore score, scoreList)
delete &score;
It will delete the the copy of object so it's undefine behaviour.
and also Qt make a copy of container before entering foreach . so even if you fix the first problem still it won't delete anything!
just change your code to :
SSensorScore newScore;
newScore.comparisonType = comparisonType;
newScore.comparisonValueType = Types::ESensorValueTypeUnknown;
newScore.comparisonValue = QVariant(config_score);
scoreList.append(newScore);
and you won't have to delete your list's item using that foreach.

Creating a vector in a method and setting it to a variable

OK so I an new to C++ and am fairly sure this should be a simple question if I can ask it right. Basically this is what I need to work:
printInfoFromVector(this->mycontroller.createVector)
This is the actual code I have:
vector<GasStation>& highPrices = this->myController.findHighestPrice();
this->findPrice(highPrices);
vector<GasStation>& findHighestPrice(){
The problem that I am having is that I can not get they types of highPrices and findHighestPrice() to match. Im fairly sure the problem is because I am passing by ref but I pretty sure that the right way to do it.
Can anyone tell me the correct way to write the assignment statement and the method head so that the types match?
If findHighestPrice is computing a new vector, then you should not return a reference, but an actual vector. Thus you would have:
vector<GasStation> findHighestPrice() { ... }
vector<GasStation> highPrices = this->myController.findHighestPrice();
For example, if you defined findHighestPrice as
vector<GasStation>& findHighestPrice() {
vector<GasStation> stations;
// ...
return stations;
}
then stations will be deallocated when the function returns and highPrices will be undefined.

C++ Linked List Error: lvalue required as left operand of assignment

Alright, I'm trying to write a program in C++ that deals with a double-linked list. Specifically, the list contains a collection of artwork objects as its nodes. In this particular function, I'm trying to remove nodes through the "sell" command, but I'm getting this error on several lines:
Error: lvalue required as left operand of assignment
I've done my research and I've found that this type of error commonly arises when you try to assign values when you actually want to compare them, or if you're trying to assign values to a constant. However, I don't think that's my problem. Here's the problem code:
// Sell At Function: This function sells the specified artwork.
void CR_ArtCollection::sell_at(string title, ostream& log)
{
CR_ArtWorks* walker = first;
while(walker != NULL)
{
if(title == walker->get_title())
{
walker->get_next()->get_prev() = walker->get_prev(); // Error
walker->get_prev()->get_next() = walker->get_next(); // Error
delete walker;
walker = NULL;
}
else walker = walker->get_next();
}
}
If anyone can point me in the right direction, I would be incredibly appreciative.
It's quite obvious - get_prev and get_next return r-values. That means you can't assign to them.
Check your interface for a method similar to set_next and set_prev and call it as:
walker->get_next()->set_prev(walker->get_prev());
walker->get_prev()->set_next(walker->get_next());
As the names suggest - get_xxxx, those methods are there so you can get the values, not also set them.
Alright, if a function returns a primitive type such as a integer or a pointer it is not legal to assign to the result of the function. That's the error you have.
One possibility would be to change your get_prev and get_next function to return references to pointers.
But I don't suggest you do that. Your code clearly needs redesigning. You should add an erase function to your linked list class. That way the pointer manipulation code will be in the CR_ArtWorks class where it belongs, instead of the CR_ArtCollection class where it doesn't.

creating an array of objects within a function of a program

could someone please tell me what I need to do in order to create an array of objects in a function (other than in the main function).
I will try to explain by making up some sort of example...
Let's say I have a program named TimeScheduler.cpp that implements the class Schedule.h
(and I have the implementation in a separate file Schedule.cpp where we define the methods).
In the declaration file we have declared two constructors
Schedule(); //the default
and
Schedule(int, int, int);//accepts three arguments
to get to the point--let's say in the main program file TimeScheduler.cpp we created our own functions in this program apart from the functions inherited from the class Schedule. so we have our prototypes listed at the top.
/*prototypes*/
void makeSomeTime();
etc.....
we have
main(){
//etc etc...
}
we then define these program functions
void makeSomeTime(){
//process
}
let's say that inside the function makeSomeTime(), we would like to create an array of Schedule objects like this
Schedule ob[]={
summer(5,14, 49),
fall(9,25,50)
};
what do I have to do to the function makeSomeTime() in order for it to allow me to create this array of objects.
The reason I ask is currently i'm having difficulty with my own program in that it WILL allow me to create this array of objects in main()....but NOT in a function like I just gave an example of. The strange thing is it will allow me to create a dynamic array of objects in the function..... like
Schedule *ob = new Schedule[n+1];
ob[2]= Schedule(x,y,z);
Why would it let me assign to a non-dynamic array in main(), but not let me do that in the function?
This is not correct:
Schedule ob[]={
summer(5,14, 49),
fall(9,25,50)
};
You appear to be trying to introduce 3 new names:
ob, which is an array of Scedules
summer, which is a Schedule
fall, which is a Schedule
You can't introduce summer and fall as new names like that. Perhaps this was just a typo, and you meant:
Schedule ob[]={
Schedule(5,14, 49),
Schedule(9,25,50)
};
...which is perfectly fine, and can exist in a function such as:
void make_schedule()
{
Schedule ob[]={
Schedule(5,14, 49),
Schedule(9,25,50)
};
}
But now you have another problem -- your make_schedule function returns void. The Schedule array you created in make_schedule is created and then just thrown away. If you want to return an array from a functtion, the best thing to do is to use a vector, and return that:
std::vector<Schedule> make_schedule()
{
Schedule ob[]={
Schedule(5,14, 49),
Schedule(9,25,50)
};
const size_t num_obs = sizeof(ob)/sizeof(ob[0]);
std::vector<Schedule> ret;
std::copy( &ob[0], &ob[num_obs], std::back_inserter(ret));
return ret;
}
A poorer alternative is to use dynamic allocation to allocate your array, and return a pointer to the first element. In this case, when using new [] it's important to note that you can only use the default constructor.
I decided that instead of using a vector, I could use an unordered_map. I didn't realize that when you 'name' an object in c++, you aren't really giving it a name...it is simply used as a sort of temporary reference. if you want to use names you are better off using a name as a sort of key value in a set. like:
string foodname;
foodname = "cake";
[foodname, 10.95]
foodname = "bread";
[foodname, 5.75]
I found help with unordered_map on http://msdn.microsoft.com/en-us/library/bb981993.aspx