c++vectorunsigned-char

Appending an unsigned char to a vector changes its value


I have the following 2D vector:

vector<vector<unsigned char>> dates;

I also have the following unsigned char array:

unsigned char date[3] = {1, 18, 108};

When I push_back this array to dates it sets all the unsigned char elements to 204:

date = ADP::addDay(date);
cout << int(date[0]) << '-' << int(date[1]) << '-' << int(date[2]) << endl;
dates.push_back({ date[0], date[1], date[2] });
cout << int(date[0]) << '-' << int(date[1]) << '-' << int(date[2]) << endl;

Output:

1-18-108
204-204-204

Is there something I am missing here? I assume this is a problem with char being converted to ASCII but I am really not sure.

EDIT

addDay() looks like this:

unsigned char* addDay(unsigned char datep[3]) {
unsigned char date[3];
date[0] = datep[0];
date[1] = datep[1];
date[2] = datep[2];
... modifys date ...
return date;
}

so it returns a pointer. Could this be a possible issue?


Solution

  • addDay is returning a pointer to a stack variable that's going out of scope; the pointer is invalid the moment the caller has access to it.

    Replace C-style arrays with std::array or std::vector (or std::tuple, given the position probably has meaning independent of the value stored) if you want this to work.

    The most minimal change would be something like:

    std::tuple<unsigned char, unsigned char, unsigned char> addDay(unsigned char datep[3]) {
        // Same code as before
        return {date[0], date[1], date[2]};  // C++17; on earlier versions, use std::make_tuple
    }
    

    You'd use the return value with:

    auto datetup = ADP::addDay(date);
    cout << int(std::get<0>(date)) << '-' << int(std::get<1>(date)) << '-' << int(std::get<2>(date)) << endl;
    

    or with nice names and structured bindings:

    auto [year, month, day] = ADP::addDay(date);
    cout << int(year) << '-' << int(month) << '-' << int(day) << endl;