代码

void log_put(const char *fmt, ...)
{
    if (NULL == fmt)
        return;

    va_list ap;
    va_start(ap, fmt);

    time_t now = time(NULL);
    struct tm st = *localtime(&now);
    printf("%04d-%02d-%02d %02d:%02d:%02d ", st.tm_year + 1900, st.tm_mon + 1, st.tm_mday, st.tm_hour, st.tm_min, st.tm_sec);

    vprintf(fmt, ap);
    printf("\n");

    va_end(ap);
}

valgrind报错

==7264== 1 errors in context 1 of 2:
==7264== Conditional jump or move depends on uninitialised value(s)
==7264==    at 0x5088079: vfprintf (in /usr/lib64/libc-2.17.so)
==7264==    by 0x4042A4: log_put (in /home/wii/svcloader/release/sapiloader)
==7264==    by 0x402999: _init_master (in /home/wii/svcloader/release/sapiloader)
==7264==    by 0x402328: env_init (in /home/wii/svcloader/release/sapiloader)
==7264==    by 0x40339C: main (in /home/wii/svcloader/release/sapiloader)

排查问题

首先这个报错是指vfprintf操作的野指针, 一般问题会出在字符串数组这类变量未初始化的时候, 那么看代码vprintf(fmt, ap);这句中只有fmt可能符合条件, 但fmt是一个转入参数,不可能对它做什么初始化, 其实这段代码并没有问题, 问题是出在调用的代码中,也就是上一级代码中转入的变量中有没做初始化造成的。

        char key[31];
        ...
        log_put("key=\"%s\"", key);

问题就出在这个变量key上。

C/C++中的数组初始化

  1. char data[32] = {0};
  2. memset( data, 0, sizeof(data));
  3. for(int i=0; i<(sizeof(data)/sizeof(char)); i++) data[i] = 0;

方法1编译结果和方法2实际是一样的,也就是说方法1最终也是调用的方法2的实现。方法1书写要比方法2简化一些,但方法2兼容性会更好。

方法3无疑是效率较差的,代码书写也最复杂。