【问题标题】:C++ Print Weird Behavior (Potential Memory Leak?)C++ 打印奇怪的行为(潜在的内存泄漏?)
【发布时间】:2019-12-17 15:30:31
【问题描述】:

我正在运行一些 C++ 代码,并注意到一些奇怪的行为。例如,我的 std::cout 打印只打印出我告诉它打印的字符串的一部分。

这是我的一小部分代码(此代码被重复调用):

std::ofstream file;
file.open("cout_img.txt", std::ofstream::out | std::ofstream::app);
std::streambuf* sbuf = std::cout.rdbuf();
std::cout.rdbuf(file.rdbuf());
std::cout << "Reached Display Function NOW";
std::string frame_file_name = std::string("demo") + std::to_string(saveImgNum) + std::string(".bmp");
std::cout << frame_file_name + '\n';

例如,在本节中,我每次只打印“splay Function NOW”,而不是完整的字符串“Reached Display Function NOW”。我什至没有打印出 frame_file_name 变量。

这是否意味着我在某处遇到了内存泄漏?如果是这样,我发布的代码部分看起来是否可疑?是不是因为我必须释放变量,比如 std::string 变量?

我还能寻找什么?我正在使用 CPython API(嵌入在 C++ 中的 Python),如果这有影响的话。

非常感谢!

【问题讨论】:

  • 打印文件的方式是使用cout &lt;&lt; file.rdbuf(),而不是将cout的缓冲区设置为文件的缓冲区。改变它,看看你是否得到了你所期望的。
  • “这是否意味着我在某处遇到了内存泄漏?” - 不太可能。内存泄漏的症状是程序内存使用量在没有明显原因的情况下增长,最终程序耗尽了可用内存。并不是说它随机行为不正确。
  • 那为什么不使用ofstream本身呢?喜欢file &lt;&lt; "your content";。我仍然无法理解您为什么要设置缓冲区。你可以通过重定向直接在命令行上控制它,通过重定向说&amp;1&gt;cout_txt,而不是在你的程序中硬编码。
  • 两个流试图共享同一个读取缓冲区是灾难的根源。
  • @cmed123 你认为这是做什么的:std::cout.rdbuf(file.rdbuf());?

标签: c++ memory


【解决方案1】:

如果您只想写入文件(作为控制台替换/日志),则没有理由通过std::cout 重定向您的输出。

我拿走了你的 sn-p 并把它剪掉了。这个:

int main()
{
    std::ofstream file;
    file.open("cout_img.txt", std::ofstream::out | std::ofstream::app);

    file << "Reached Display Function NOW\n";
    std::string frame_file_name = std::string("demo") + std::to_string(17 /*saveImgNum*/) + std::string(".bmp");
    file << frame_file_name + '\n';

    return 0;
}

生成一个文件cout_img.txt,其中包含:

Reached Display Function NOW
demo17.bmp

编辑:此外,您还可以在 Windows 应用程序中启用控制台。快速搜索到this answer。将以下代码添加到您的WinMain,控制台将工作:

    AllocConsole();
    #pragma warning( disable : 4996 )
    freopen("conin$", "r", stdin);
    freopen("conout$", "w", stdout);
    freopen("conout$", "w", stderr);
    printf("Debugging Window:\n");
    std::cout << "Testing the console 1 2 3" << std::endl;

如果您进行更彻底的搜索,您甚至可以找到不使用已弃用方法的方法 (freopen)。但如图所示,它确实为我刚刚创建的用于测试的 Windows 应用程序添加了一个正常运行的控制台。

【讨论】:

  • 非常感谢!对于您关于 AllocConsole() 的第二个解决方案,似乎 cout 仅在其范围内有效,对吗?如果我在不同的功能中使用 cout,它不会打印到该控制台
  • @cmed123 不正确。 AllocConsol 对任何 std::cout 的工作方式都相同,除非您修改 std::cout 以使其行为不同。如果您希望控制台自动显示,您可以将 VS 中的项目属性更改为 Console Application
  • @Everyone 感谢您的澄清。你是对的,我也刚刚测试过。但事实证明,如果我使用 CPython API,控制台无法显示 Python 输出。是因为 Python 通过了不同的输出位置吗?除非我又弄错了
  • @cmed123 如果您正在运行子进程,它会得到 ow 输出流。你所能做的就是连接它,类似于 Visual Studio 为编译工具所做的。在某处的 SO 上找到了该问题的答案,显然您正在解决 XY 问题。
猜你喜欢
  • 1970-01-01
  • 2012-07-06
  • 1970-01-01
  • 2015-05-09
  • 2021-03-28
  • 2020-12-19
  • 2011-04-01
  • 2012-03-07
相关资源
最近更新 更多