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
)