在静态变量初始化中使用 cout 时出现 C++ 分段错误 [英] C++ Segmentation Fault when using cout in static variable initialization

查看:43
本文介绍了在静态变量初始化中使用 cout 时出现 C++ 分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,我使用 cout 来发出调试信息.代码在静态全局变量的初始化中执行,即在程序执行的早期.当我使用自己的构建脚本构建程序时,它在第一次使用 cout 时出现段错误(只有一个字符串文字被转移到 cout,所以它不能是值).我使用 valgrind 检查早期对无效位置的写入,但没有(也没有可能生成这些写入的代码,我在输出之前没有做太多).当我将源代码复制到 Eclipse 项目并让 Eclipse 内置构建器构建它时,一切正常.我没有使用任何奇怪的构建器设置,只是用 -ggdb -std=c++0x 编译,这是仅有的两个标志.

I have a program where I use cout to emit debug information. The code is executed in the initialization of a static global variable, i.e. quite early in the program execution. When I use my own build script to build the program, it segfaults at the first use of cout (only a string literal is shifted into cout, so it cannot be the value). I used valgrind to check for earlier writes to invalid locations, but there are none (and there is also no code that would be likely to generate those writes, I dont do too much before the output). When I copy the source code to an eclipse project and let the eclipse built-in builder build it, then everything works fine. I used no weird builder settings simply compiled with -ggdb -std=c++0x, these are the only two flags.

那么,如果之前没有无效写入,带有字符串文字的 cout 段错误的原因是什么?构建配置对此有何影响?

So what can be the reason that a cout with a string literal segfaults, if there were no invalid writes before? How can the build configuration affect this?

(对不起,我不能给你一个最小的例子,因为这个例子可以简单地在你的机器上编译,就像我在使用 eclipse builder 时所做的那样)

(I am sorry I can give you no minimal example, as this example would simply compile fine at your machine, as it does for me when using the eclipse builder)

这是堆栈跟踪:

0x00007ffff7b6d7d1 in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib   /x86_64-linux-gnu/libstdc++.so.6
(gdb) backtrace
#0  0x00007ffff7b6d7d1 in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x00007ffff7b6dee9 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00007ffff7b6e2ef in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) ()
  from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00000000004021be inTest::fill (this=0x6120f8, funcs=...) at inTest.cpp:92

最后一帧是我的代码.第 92 行简单地写着:

The last frame is my code. Line 92 simply reads:

std::cout << "Test";

推荐答案

正如 Luchian 所指出的,你不能在第一个之前使用 std::coutios_base::Init 的实例已构建.你不必然而,定义一个实例;包括 <iostream> 应该就够了.

As Luchian has pointed out, you cannot use std::cout before the first instance of ios_base::Init has been constructed. You don't have to define an instance, however; including <iostream> should be enough.

初始化顺序在单个翻译单元中定义的.如果您在所有具有静态的文件的顶部包含 <iostream>实例,你应该没问题.如果静态对象的构造函数然而,在另一个翻译单元中调用一个函数,输出是在该翻译单元中,仅包含 <iostream> 是不够的仅在执行输出的翻译单元中.你必须包括它在定义静态变量的翻译单元中.甚至如果他们不做任何输出.

Order of initialization is defined within a single translation unit. If you include <iostream> at the top of all files which have static instances, you should be OK. If the constructor of a static object calls a function in another translation unit, however, and the output is in that translation unit, it is not sufficient to include <iostream> only in the translation unit which does the output. You must include it in the translation unit where the static variable(s) are defined. Even if they don't do any output.

这篇关于在静态变量初始化中使用 cout 时出现 C++ 分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆