c++ - std::bind 一个成员函数到 nullptr 处的一个实例导致看似随机的 this 指针

标签 c++ c++11 undefined-behavior

我已经在 gcc-4.8(通过 Coliru)和 Visual Studio 2013 RC 上测试了以下程序:

#include <iostream>
#include <functional>

using namespace std;

struct foo {
    void bar() {
        cout << "this = " << this << endl;
    }
};

int main() {
    try {
        foo *ptr = nullptr;
        function<void ()> fun = bind(&foo::bar, *ptr);
        fun();
    } catch (const bad_function_call &e) {
        // never reached
        cout << "bad_function_call thrown: " << e.what() << endl;
    } 

    cin.get();
}

我知道我在这里通过取消引用 nullptr 导致了未定义的行为,但我不明白我的代码的输出。在我的理解中,这应该导致 bad_function_call(因为根据我的猜测,这是调用此 std::function 时应该抛出的内容)或至少打印“this = 0”。

事实并非如此。输出是“this =”后跟一些指针,在我测试的两个编译器上都不是 nullptr。但是,访问它会导致段错误。

标准中是否有条款对此进行了规定?或者它只是实现定义的“未定义行为”?

编辑:作为补充:以下代码在我的机器上输出“this = 0”:

foo *ptr = nullptr;
ptr->bar();

最佳答案

bind 会存储参数的拷贝。参数是 foo 类型(因为您传递的是 *ptr),因此会生成一个拷贝。当然,该拷贝获得了一个无效参数作为源,但未使用该参数,因此这似乎有效。结果,foo 的新实例存储在绑定(bind)对象中,这就是您看到的地址。

当你说你看到一个段错误时,你指的是你的真实代码,而不是你在这里给出的例子,对吧?在您的真实代码中,我猜 copy-ctor 似乎可以工作,但会创建一个实例,当您访问其(可能无效的)成员时会导致段错误。

关于c++ - std::bind 一个成员函数到 nullptr 处的一个实例导致看似随机的 this 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19210281/

相关文章:

c++ - 由定义指令定义的类名。可能的?

c++ - 如何通过 .props 文件设置调试符号路径

c++11 - C++11中的并发阻塞队列

c++ - std::make_pair、c++11 和显式模板参数

c++ - std::async with std::unique 不编译

c - "p = p + (*p)++ * 3 + c;"会导致未定义的行为吗?

c++ - 我如何才能真正使用std::chrono类型而不冒溢出和未定义行为的风险?

c++ - boost 变体 : How can I do a visitor that returns the type that was set?

c++ - 将字符串分解为单独的元素

c - 为什么我会收到段错误?