std :: ofstrean不能与-O3一起使用

时间:2015-05-05 14:22:37

标签: c++ fstream

以下代码,只需

1)从命令行参数中获取输入文件名,比如in.txt

2)将文件名附加到" cdf _"

3)打开一个名为cdf_in.txt的文件

4)只需从(每行中的一个数字)读取每一行并将其发送到输出文件。

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

int main(int argc, char* argv[]) 
{
  char *ben = argv[1];    // example: in.txt
  ifstream fin (ben);
  char res[30];

  char *o1 = "cdf_";
  strcat(res, o1);
  strcat(res, ben);
  ofstream fout (res, std::ofstream::out);   // will be cdf_in.txt
  cout << res << endl;

  uint64_t num;  uint64_t sum = 0;
  while (fin >> num) {
    fout << num << endl;
  }
  return 0;
}

通过在没有任何优化的情况下运行程序,它可以正常运行。但是,通过指定-O3,它无法创建输出文件。为什么???

$ g++ -o cdf cdf.cpp
cdf.cpp: In function ‘int main(int, char**)’:
cdf.cpp:19: warning: deprecated conversion from string constant to ‘char*’
$ ./cdf in.txt
cdf_in.txt
$ ls cdf*
cdf  cdf.cpp  cdf_in.txt  cdf.py
$ cat cdf_in.txt
10
5
3
2
1

$ rm cdf_in.txt
$ g++ -O3 -o cdf cdf.cpp
cdf.cpp: In function ‘int main(int, char**)’:
cdf.cpp:19: warning: deprecated conversion from string constant to ‘char*’
$ ./cdf in.txt
cdf_in.txt
$ ls cdf*
cdf  cdf.cpp  cdf.py

为什么fout无法使用-O3

1 个答案:

答案 0 :(得分:9)

您的strcat(res, o1);取决于res[0] == '\0',这可能是真的,但不保证(res是未初始化的本地,因此其内容未知/指定)。< / p>

当你不进行优化时,它可能会被初始化为零,但是当你没有进行优化时,它可能会被初始化为零。

您可以通过初始化res或使用strcpy代替strcat来修复要复制的第一个项目(但这仍然存在可能的缓冲区溢出问题,因此请参阅下面的更好的替代方案。)

或者,当然,您可以编写更像C ++而不是C的代码,并使用std::string而不是char数组。

std::string fname("cdf_");
fname += argv[1];

std::ofstream fout(fname.c_str()); // just `fout(fname)` with a C++11 compiler

如果您真的想出于某种原因编写类C代码,在这种情况下使用sprintf可能会更容易:

char res[30];

sprintf(res, "cdf_%35s", argv[1]);

std::ofstream fout(res);