C ++中奇怪的cout行为

时间:2011-02-19 20:45:56

标签: c++ cout undefined-behavior

在我的程序中使用cout时出现了一些奇怪的行为,类似于以下内容:

...
char *input = realpath(argv[1], NULL);
char *output = argv[2];

char *tarout = new char[strlen(output)+6];
strcpy(tarout, output);
strcat(tarout, ".temp");

cout << "Tarout: " << tarout << endl;

int tRet = tarball(input, tarout);
if(tRet != 1) {
    cerr << "Error: Could not compress directory!\nHalting package creation!" << endl;
    return 0;
}

int gRet = gzip(tarout, output);
if(gRet != 1) {
    cerr << "Error: Could not compress directory!\nHalting package creation!" << endl;
    return 0;
} else {
    cout << "TAROUT: " << tarout << endl;
    if((remove(tarout))!=0) {
        cerr << "Warning: Could not delete temporary file!" << endl;
        return 0;
    }
}
...

基本上这个程序创建一个tar文件,然后用gzip压缩它,这不是100%的实际代码,所以它可能不会给出与我收到的相同的奇怪行为。

如果我删除了第一个cout << "TAROUT: " << tarout << endl;,则第二个cout << "TAROUT: " << tarout << endl;将不返回任何内容,并且临时文件不会被删除,为什么会这样?

1 个答案:

答案 0 :(得分:3)

new / malloc不初始化内存,所以我很确定你在tarout结束时没有NULL终止符。

我怀疑如果您通过调试器运行原始代码或只是打印*(tarout + 5),您会发现那里没有'0'。

鉴于你的评论重新使用std :: string,我会写:

const char * file_ext = ".temp";

// no magic numbers...and an obvious + 1 for null terminator
size_t len = strlen(output)+strlen(file_ext)+1;

char *tarout = new char[len];

memset(tarout, 0, len);

strcpy(tarout, output);
strcat(tarout, file_ext);

// If you feel memset is wasteful, you can use
*(tarout+len-1) = 0;

...