可能未定义的行为,但为什么?

时间:2017-10-04 21:02:52

标签: c++ debugging undefined-behavior

我在dll中添加了一个新类,它是解决方案的一部分。一切正常,直到我开始在this问题中讨论错误,然后我将使用调试器启动解决方案。这意味着调试器正在捕获一些不好的东西,可能是堆损坏,尽管它没有指出它确切位置。

我将问题缩小到我添加的类,如果我删除它,解决方案调试正常,没有错误。但显然,我添加的课程没有任何问题!

所以我评论了我的课程并添加了一个新的简单(虚拟)类Book,只是为了看它是否会产生相同的错误,但它不会!然后我让它看起来类似于我添加的类(派生自ofstream),它仍然可以正常调试,没有错误。

我对它进行了评论并取消注释了我的原始类,再次调试时出现错误!我浏览了这个类并且只留下了构造函数/析构函数,现在我可以调试它,错误在这里也消失了。我带回了删除代码(使用撤消,以便完全恢复),这次它工作(当它不是之前)并将调试正常,而不会抛出该损坏错误!

所以这听起来很像未定义的行为,但这是一个非常轻量级的独立类,它被正确实例化,所以未定义的行为仍然是可疑的?如果是这样,为什么在这种情况下会导致这种行为?

以下是我的.h和.cpp文件供参考

class lfstream : public std::ofstream
{
public:
    lfstream();
    ~lfstream();

    void log(const std::string &text, int threadID);
};

#ifdef _LOGDLL
    #define API __declspec(dllexport)
#else
    #define API __declspec(dllimport)
#endif

API extern lfstream logstream;

/*
class Book : public std::ofstream
{
public: 
    Book();
    ~Book();
    int WordCount();
};

API extern Book book;
*/

.cpp文件

static char logfname[] = "debug.txt";

lfstream::lfstream(): std::ofstream( logfname )
{
}

lfstream::~lfstream()
{
}

void lfstream::log(const std::string &text, int threadID)
{
    const time_t ctt = time(0);
    *this << std::setw(40) << std::left << text << " thread id = " << threadID << "\t" << asctime(localtime(&ctt)); // << std::endl;
}

lfstream logstream;

/*
Book::Book() : std::ofstream("crash.txt")
{
}
Book::~Book()
{
}

int Book::WordCount()
{
    return 50;
}

Book book;
*/

1 个答案:

答案 0 :(得分:2)

您的代码显示您希望在不同的线程上调用。

我们在代码中没有看到线程同步或关键部分。

您需要使用关键部分来防范竞争条件。竞争条件为Undefined Behaviour

最常见的标准C ++解决方案是使用带有std::mutex的{​​{1}}来确保单个线程可以位于(a)代码的关键部分。

采样/想法:

std::lock_guard