Home > Back-end >  Weird value and overriding text on variadics
Weird value and overriding text on variadics

Time:11-12

I'm trying to create a logging system where you push a log string into a vector and then print all the logs by looping through the vector, but there seems to be an issue where the strings inside my vector are getting replaced by the most recent string pushed, as well as weird characters being added.

struct color {
    color(unsigned int nr, unsigned int ng, unsigned int nb, unsigned int na) : r(nr), g(ng), b(nb), a(na) {}
    unsigned int r, g, b, a;
};

struct info {
    const char* text;
    float time;
    color col;
    info(const char* ntext, float ntime, color ncol) : text(ntext), time(ntime), col(ncol) { }
};

class event_logger {
public:
    std::vector<info> info_list;
    
    void add_log_messasge(color col, const char* message, ...) {

        char fmsg[512] = { '\0' };
        va_list list;
        va_start(list, message);
            vsprintf_s(fmsg, 512, message, list);
        va_end(list);

        this->info_list.push_back(info(fmsg, 10.0f, col));

        // limit to 12 messages at a time
        if (this->info_list.size() > 12)
            this->info_list.pop_back();
    }

    void print_log_info() {
        /* Don't run if the vector is empty. */
        if (!info_list.empty())
        {
            for (size_t i = 0; i < info_list.size(); i  )
            {
                printf_s("%s\n", info_list[i].text);
            }
        }
    }
};

int main() {
    event_logger log;
    log.add_log_messasge(color(255, 255, 255, 255), "welcome (%.3f, %s)", 3.14f, "WHAT THE FUCK");
    log.add_log_messasge(color(255, 255, 255, 255), "unlucky %s", "dude");
    log.print_log_info();
}

Does anyone know what the problem is?

CodePudding user response:

your struct

struct info {
    const char* text;
    float time;
    color col;
    info(const char* ntext, float ntime, color ncol) : text(ntext), time(ntime), col(ncol) { }
};

is copying an address to a local variable fmsg. The life time of fmsg is circumscribed in the scope of add_log_messasge (you got a typo). Storing the address of a local variable and use it externally of its scope is undefined behavior.

use a std::string to store the value of fmsg by copying it and it will work.

struct info {
    std::string text;
    float time;
    color col;
    info(const char* ntext, float ntime, color ncol) : text(ntext), time(ntime), col(ncol) { }
};

You need to change your way of printing it by using c_str()

   void print_log_info() {
        /* Don't run if the vector is empty. */
        if (!info_list.empty())
        {
            for (size_t i = 0; i < info_list.size(); i  )
            {
                printf_s("%s\n", info_list[i].text.c_str());
            }
        }
    }

Note: Your check that is using empty isn't really necessary since an empty vector call of size returns 0 which will never start your for loop (i=0 can't be lower of size 0)

  • Related