C++ 为什么EXPECT_EQ不能正确地接受方法的结果作为参数?

C++ 为什么EXPECT_EQ不能正确地接受方法的结果作为参数?,c++,googletest,C++,Googletest,我正在学习数据结构,所以我通过模板创建了一个堆栈类,并使用gtest对其进行测试 而在使用EXPECT_EQ宏的两种方法中,它显示了不同的测试结果 这样,最后一行仅在我使用“运行”配置而不是“调试”配置的情况下触发异常。我发现它总是发生在最后一个stack->pop方法中,只要我完全清除堆栈并且堆栈中有多个元素 测试(堆栈,isOK){ 自动堆栈=新堆栈(); 堆栈->推送(123); 堆栈->推送(123); 堆栈->推送(123); auto-ret=stack->Pop(); 预期均衡器

我正在学习数据结构,所以我通过模板创建了一个堆栈类,并使用gtest对其进行测试

而在使用EXPECT_EQ宏的两种方法中,它显示了不同的测试结果

  • 这样,最后一行仅在我使用“运行”配置而不是“调试”配置的情况下触发异常。我发现它总是发生在最后一个
    stack->pop
    方法中,只要我完全清除堆栈并且堆栈中有多个元素
  • 
    测试(堆栈,isOK){
    自动堆栈=新堆栈();
    堆栈->推送(123);
    堆栈->推送(123);
    堆栈->推送(123);
    auto-ret=stack->Pop();
    预期均衡器(ret,123);
    EXPECT_EQ(stack->Pop(),123);
    EXPECT_EQ(stack->Pop(),123);//这一行。
    }
    
    例外情况表明:

    Running main() from D:\Homework\DataStructure\C++\Test\lib\googletest-master\googletest\src\gtest_main.cc
    Running 1 test from 1 test suite.D:\Homework\DataStructure\C++\Test\tests\StackTest.cpp:15: Failure
    Expected equality of these values:
      stack->Pop()
        Which is: -2147483136
      123
    
    1 test from 1 test suite ran. (1 ms total)
    
  • 这样,所有代码都运行良好
  • 测试(堆栈,isOK){
    自动堆栈=新堆栈();
    堆栈->推送(123);
    堆栈->推送(123);
    堆栈->推送(123);
    auto-ret=stack->Pop();
    预期均衡器(ret,123);
    EXPECT_EQ(stack->Pop(),123);
    ret=stack->Pop();
    期待_EQ(ret,123);//一切正常。
    }
    
    Stack.h

    //
    //anon于2019/4/15创建。
    //
    #ifndef数据结构堆栈
    #定义数据结构栈
    #包括“Definition.h”
    样板
    类堆栈{
    const int stack_init_size=1;
    常数int stack_增量=1;
    受保护的:
    T*base;
    T*top;
    int堆栈大小;
    公众:
    堆栈();
    ~Stack();
    状态清除();
    bool empty();
    int length();
    T GetTop();
    状态推送(te);
    T Pop();
    };
    样板
    Stack::Stack(){
    堆栈大小=堆栈初始大小;
    基=(T*)malloc(sizeof(T)*堆栈大小);
    顶部=底部;
    }
    样板
    状态堆栈::清除(){
    返回0;
    }
    样板
    bool Stack::empty(){
    返回false;
    }
    样板
    int Stack::length(){
    if(top==nullptr){
    返回0;
    }
    否则{
    自动值=(上-基);
    返回val;
    }
    }
    样板
    状态堆栈::推送(TE){
    如果(长度()==堆栈大小){
    自动旧底=底;
    基本=(T*)实位(基本,(堆栈大小+堆栈增量)*sizeof(T));
    如果(!base)退出(错误);
    如果(基础!=旧基础){
    顶部=底部+(堆叠尺寸*尺寸(T));
    }
    堆栈大小+=堆栈增量;
    }
    *top=e;
    top++;
    返回OK;
    }
    样板
    T Stack::Pop(){
    如果(长度()==0)
    退出(错误);
    自动返回=*(前1名);
    顶部--;
    返回ret;
    }
    样板
    堆栈::~Stack(){
    删除基数;
    }
    样板
    T Stack::GetTop(){
    如果(长度()==0)
    退出(错误);
    返回*(前1名);
    }
    #endif//数据结构堆栈
    
    尝试以下推送方法:

    template<class T>
    Status Stack<T>::Push(T e) {
      if (length() == stack_size) {
        stack_size += stack_increment;
        base = (T *)realloc(base, stack_size * sizeof(T));
        if (!base) std::exit(ERROR);
        top = base + stack_size;
      }
      *top++ = e;
      return OK;
    }
    
    模板
    状态堆栈::推送(TE){
    如果(长度()==堆栈大小){
    堆栈大小+=堆栈增量;
    base=(T*)realloc(base,stack_size*sizeof(T));
    如果(!base)标准::退出(错误);
    顶部=底部+堆叠尺寸;
    }
    *top++=e;
    返回OK;
    }
    
    将整数
    x
    添加到
    T*
    类型的指针时,指针的值不会增加
    x
    。它将指针
    x
    “插槽”向右移动,其中一个“插槽”是一个
    T
    占用的空间

    所以当你写
    top=base+stack\u size
    那么
    top
    的实际值是
    base+(堆栈大小*sizeof(T))


    有关更多信息,请使用谷歌“指针算法”或查看

    它可以,您只是在某个地方有一个bug。你为什么要推同样的价值观?尝试按一次不同的按钮以进行更好的测试,并检查结果。
    stack->Pop()
    有副作用,
    EXPECT\u EQ
    是一个宏。不能保证每次调用
    EXPECT\u EQ
    时,
    stack->Pop()
    只会被调用一次。更自然的方法是
    EXPECT_EQ(123,stack->Pop())stack->Pop()
    ,尽管它会多次计算123(这没有副作用)。@Gojita我想不会。在构造时,
    top==base
    top-base
    则为
    0
    ,预期为空堆栈;)@不,不是。既然你是一个初学者,我就给你上一堂宝贵的课,这是我辛苦学来的。当面对意想不到的行为时:你错了。您使用的库是正确的,编译器是正确的,操作系统是正确的,CPU是正确的。你错了。重复它,直到它在你的大脑中被硬编码。修复代码;)@非常感谢我终于明白你的意思了(∩_∩)O我不是以英语为母语的人)。错误是
    top=base+(stack_size*sizeof(T));
    并且只有在“RUN”设置中,realloc始终创建一个新的内存空间来触发此语句。