Operator Overloading / Printing

Test code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main(){
    Status_List s_list;

    s_list.add_status("Blind", 2);
    s_list.add_status("Stun", 5);
    s_list.add_status("Deaf", 3);
    s_list.add_status("Weak", 4);
    print_status(s_list);

    for(int i = 0; i < 5; ++i){
        --s_list;
        print_status(s_list);
    }

    return 0;
}

void print_status(Status_List s_list){
    for(int i = 0; i < s_list.status.size(); ++i){
        std::cout << s_list.status[i]->get_eff() << ", " << s_list.status[i]->get_dur() << std::endl;
    }
}


Relevant functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Status_List& Status_List::operator--(){
    int i = 0;

    while(i < status.size()){
        if(status[i]->get_dur() <= 1)
            rem_status(i);
        else{
            status[i]->dec();
            ++i;
        }
    }

    return *this;
}

Status_List Status_List::operator--(int){
    Status_List tmp(*this);
    operator--();
    return tmp;
}


Classes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Status{
 public:
	Status(std::string eff = "", short dur = 0) : effect(eff), duration(dur) {}

	void dec() {duration--;}
	short get_dur() {return duration;}
	std::string get_eff() {return effect;}

 private:
	std::string effect;
	short duration;
};

class Status_List{
 public:
	~Status_List();

	void add_status(std::string, short);
	Status_List& operator--();
	Status_List operator--(int);

	friend void print_status(Status_List);

 private:
	std::vector<Status *> status;

	void rem_status(int);
};

...

void Status_List::rem_status(int index){
	Status * stat = status[index];
	status.erase(status.begin() + index);
	delete stat;
}


Output

./a.out 
Blind, 2
Stun, 5
Deaf, 3
Weak, 4
Segmentation fault (core dumped)


The above code gives the above output. Using various methods of testing (valgrind, gdb, and good old diagnostic cout), I have determined that the segmentation fault occurs after the completion of --s_list; but before the modified list has completed printing. I believe I may have messed up the operator overload functions, but I don't see how I did it. If anybody has any insight into what's going on here, I would love to hear it.
In Status_List& Status_List::operator--() you get the size of the vector only once (line 4). If you delete an entry, the size of the vector decreases by one, but you're still using the original size of the vector as the upper limit.
Two questions:
1) Since I'm using that as the test, wouldn't that mean it retrieves that information every time it is tested?
2) How would that cause a segmentation fault in the case (as this case is) when no elements have been removed?
Looks to me like rem_status will remove more than just one item. it erases from the beginning to the index which could be multiple things. That could result in a memory leak. Overall, this design is horrendous. First of all, an operator-- should not be destroying memory. Although you can overload operators to do whatever you want, it is not advisable to design them to do nonsensical, or unintuitive things. (e.g., operator+ should add, operator- should substract, operator* should multiply or dereference). Of course, you could write your operator+ to do all kinds of crazy and unintuitive things. The compiler won't stop you from doing dumb things.

You have no posted the code in a way that would allow others to easily compile and run. I recommend that you stop into this with the debugger and monitor the variables. The debugger should easily be able to tell you the root cause.
@kemptofighter
The first line of http://www.cplusplus.com/reference/vector/vector/erase/ makes your entire post nonsensical. The rem_status function specifically tracks memory like an iterator does, removes that ONE element from the vector, and then uses the temporary pointer to deallocate the memory properly. The purpose of the operator-- is to reduce the value of duration in every element. Removing an element when the lifetime of that element has expired is one of the crucial elements of the program, and I'm not bout to leave it up to the user to clean up. That type of design is uh...what was the word? Oh, "horrendous.'
Topic archived. No new replies allowed.