Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ list not resizing after set difference

Consider the following code:

#include <algorithm>
#include <iostream>
#include <list>

int main() {
    std::list<int> v = {1, 3, 4};
    std::cout << v.size() << std::endl;
    v.resize(0);
    std::cout << v.size() << std::endl;
}

after compiling the output, as expected, is

3
0

Now I add a set difference.

#include <algorithm>
#include <iostream>
#include <list>

int main() {
    std::list<int> x = {1, 3, 4};
    std::list<int> y = {1, 2, 3, 5};
    std::list<int> v;
    x.sort();
    y.sort();
    std::cout << v.size() << std::endl;
    auto it =
        std::set_difference(x.begin(), x.end(), y.begin(), y.end(), v.begin());
    std::cout << v.size() << std::endl;
    v.resize(0);
    std::cout << v.size() << std::endl;
}

and the output is

0
4
4

why does the resize work for the first example, but not in the second?

like image 698
Joseph Summerhays Avatar asked Jul 01 '21 21:07

Joseph Summerhays


People also ask

How to change the size of list in C++?

The C++ function std::list::resize() changes the size of list. If n is smaller than current size then extra elements are destroyed. If n is greater than current container size then new elements are inserted at the end of list.

How to resize a list in C++ STL?

The list::resize () is a built-in function in C++ STL which is used to resize a list container. It takes a number n as parameter and resizes the list container to contain exactly n elements. If the list already has more than n elements, then the function erases the elements from the list except the first n element.

What happens if a list is smaller than the current size?

If n is smaller than current size then extra elements are destroyed. If n is greater than current container size then new elements are inserted at the end of list. Following is the declaration for std::list::resize () function form std::list header.

What happens if the content is smaller than the container size?

If n is smaller than the current container size, the content is reduced to its first n elements, removing those beyond (and destroying them). If n is greater than the current container size, the content is expanded by inserting at the end as many elements as needed to reach a size of n.


Video Answer


1 Answers

This is because it is undefined behavior.

The last parameter to std::set_difference is an output iterator. You are passing in v.begin().

This returns a pointer to the beginning of an empty list. In order for your intended code to work as advertised, the *iter++ operation of the output iterator must add new values to the list.

Unfortunately, no matter what you do with the iterator that's returned by begin(), nothing that you do to it will make the list any bigger or smaller than it already is. It is just iterating over the existing contents of the list.

At this point, you're pretty much in undefined behavior territory, and any results you get will be completely nonsensical (if not an immediate crash).

Instead of passing in v.begin(), you need to use std::back_insert_iterator instead.

like image 104
Sam Varshavchik Avatar answered Oct 21 '22 09:10

Sam Varshavchik