故意的朋友类redifinition和-fstack-protector

时间:2018-02-21 08:53:12

标签: c++ friend stack-smash

我一直在尝试测试不同.cpp文件中的朋友类的多个定义是否有效。为此,我在main_class.hpp文件中定义了一个主类:

class main_class
{
private:
    int a;
    int b;

    int gimme_a()
    {
        return a;
    }

public:
    main_class(int a, int b) : a(a), b(b) {}

    int gimme_b()
    {
        return b;
    }

friend class main_class_friend;
};

然后我定义了main_class_friend两次,首先是在main_friend_class1.cpp文件中:

class main_class_friend
{
    main_class c;
public:

    main_class_friend() : c(10, 10) {}

    int gimme_a()
    {
        return c.gimme_a();
    }

    int gimme_b()
    {
        return c.gimme_b();
    }
};

和相应的公共测试功能:

void test1()
{
    main_class_friend ff;
    std::cout << "Gimme a: " << ff.gimme_a() << " and gimme b: " <<
        ff.gimme_b() << std::endl;
}

然后我在main_class_friend中定义了第二个main_friend_class2.cpp以及相应的公共测试函数:

class main_class_friend
{
private:
    main_class ca;
    int c;
public:

    main_class_friend() : ca(9 ,9), c(11) {}

    int gimme_a()
    {
        return ca.gimme_a();
    }

    int gimme_b()
    {
        return ca.gimme_b();
    }

    int gimme_c()
    {
        return c;
    }
};


void test2()
{
    main_class_friend ff;
    std::cout << "Gimme a: " << ff.gimme_a() << " and gimme b: " << ff.gimme_b() 
        << " and gimme c: " << ff.gimme_c() << std::endl;
}

最后我在main中调用了test1test2函数:

int main()
{
    test1();
    test2();
    return 0;
}

编译程序(g++没有错误),然后运行它。输出是:

Gimme a: 9 and gimme b: 9
*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)

对我来说真正奇怪的是,abmain_friend_class2.cpp内的构造函数初始化,而不是来自main_friend_class1.cpp的{​​{1}}函数是test1定义

然后我发现当用-fstack-protector标志编译程序时,可以很容易地调试堆栈粉碎。所以我再次编译它,然后程序的输出是:

Gimme a: 9 and gimme b: 9
Gimme a: 9 and gimme b: 9 and gimme c: 11

所以没有更多的堆栈粉碎问题,但test1test2函数都使用main_friend_class2.cpp文件中的构造函数。

周围发生了什么?我不明白。如果没有缓冲区溢出,为什么会出现堆栈粉碎错误,因为没有使用任何缓冲区?

我的第二个问题是:有没有办法定义多次main_class_friend,但是在不同的文件中使用它们使它们对于使用该类的文件是“私有的”?

0 个答案:

没有答案
相关问题