【问题标题】:Address 0x20ec8348e5894855 is not stack'd, malloc'd or (recently) free'd地址 0x20ec8348e5894855 没有被堆栈、malloc 或(最近)释放
【发布时间】:2017-09-13 04:18:14
【问题描述】:

我有两个自己的库,例如“IDA”和“XIDA”。并且我想让它们通过回调函数一起通信。

国际开发协会:
ida.h, ida.cpp, ida_a.h, ida_a.cpp

西达:
xida.h, xida.cpp, xida_a.h, xida_a.cpp

国际开发协会:
ida_a.h:

class IDA_A
{
private:
    XIDA *mXIDA;
public:
    static int IDA_Callback(void* this_ptr, void *vPara ){
        std::cout << "IDA -- " << "INCOMING CALLBACK == NULL" << std::endl;
    }
}

ida_a.cpp:

void IDA_A::Init(std::string vIdent){
    this->mXIDA = new XIDA( (void*) &this->IDA_Callback);
}

现在西达:

xida.h:

class XIDA{
public:
    XIDA(void *vPara);
};

xida.cpp:

XIDA_A m_XIDA_A;

XIDA::XIDA(void *vPara){
    std::cout << "TEST XIDA ---- A" << std::endl;
    m_XIDA_A.Init(vPara);
}

xida_a.h:

typedef int(*IDACallback) (void*, void*);

class XIDA_A{
private:
    IDACallback mIDACallback;
public:
    void Init(void *vPara);
}

xida_a.cpp:

1 void XIDA_A::Init(void *vPara){
2 int nErr = 0;
3    cout << "XIDA -- INIT A **************************************************  " << vPara << endl;
4   try{
5       this->mIDACallback = *static_cast < IDACallback* > (vPara);
6   } catch (...){
7       nErr = 1;
8    }
9   if(nErr == 0){
10      cout << "XIDA -- INIT B **************************************  " << this->mIDACallback << endl;
11      this->mIDACallback(NULL, NULL); // <------ HERE IS THE ERROR
12  }
13 }

正常调用时(通过终端和路径/bin),错误是:

Speicherzugriffsfehler (engl. memory access error <?>)

使用 Valgrind:

XIDA -- INIT A **************************************************  0x4e40a19
XIDA -- INIT B **************************************  1
==20001== Jump to the invalid address stated on the next line
==20001==    at 0x20EC8348E5894855: ???
==20001==    by 0x504C690: XIDA::XIDA(void*) (xida.cpp:10)
==20001==    by 0x4E405CB: IDA_A::Init(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (ida_a.cpp:37)
==20001==    by 0x4E3FE9F: IDA::IDA(char const*) (ida.cpp:13)
==20001==    by 0x401932: main (main.cpp:13)
==20001==  Address 0x20ec8348e5894855 is not stack'd, malloc'd or (recently) free'd

所以,现在我知道错误在哪里,但我不知道如何解决它。

【问题讨论】:

  • 请尝试制作一个完整的(可编译的)示例。例如,类中缺少 IDA_A:: init () 的声明。
  • 要解决此问题,请将所有void *s 替换为适当的类型,并让编译器为您找到真正的错误,由于传递了错误的对象,这很可能表现为编译错误通过以前不透明的void *。在现代 C++ 中,很少有情况仍然需要使用 void *s。
  • 如果不使用魔法、精神力量或猜测,就无法在当前状态下回答问题。请组装一个minimal reproducible example。题外话,这段代码忽略了 C++ 的一些基本原则,从而引发了很多可能的错误。
  • @Sam Varshavchik:正如我之前已经写过的,我将 void* paras 更改为回调的 typedef,这是有效的。但我仍然想知道如何让它与 void* 一起工作。解决方案是,我可以使用“this->mIDACallback = (IDACallback) vPara;”而不是“this->mIDACallback = static_cast > (*vPara);”。你让我明白了。谢谢你,先生!

标签: c++ callback shared-libraries


【解决方案1】:

IDA_A::Init 实际上并未声明,但除此之外,您将 vPara(包含指向函数的指针)转换为指向函数指针的指针,然后取消引用它:

this->mIDACallback = *static_cast < IDACallback* > (vPara);

应该是

this->mIDACallback = static_cast < IDACallback > (vPara);

【讨论】:

  • 如果你反汇编0x20EC8348E5894855(考虑到它是little-endian)你会得到一个函数序言:push rbp; mov rbp,rsp; sub rsp,0x20
  • 我得到一个错误:从类型 'void*' 到类型 'IDACallback {aka int ()(void, void*)}' this->mIDACallback = static_cast (vPara); ^
  • 但是在您发布的代码中,它的声明方式不同,typedef int(*IDACallback) (void*, void*);static_cast 应该可以正常工作。
  • 是的,typedef 和作为回调给出的函数都等于 int (void*, void*),但是您的解决方案不起作用。顺便说一句,我之前也尝试过,还有其他变体。这是我在此处发布的原因之一,因为我确实自己找到了解决方案,我“通常”认为,这段代码应该可以工作……但事实并非如此。
  • @ Sam Varshavchik:我现在已将所有 void* 更改为 typedef int(void*, void*) 并且这有效。现在我将再次对 void* 进行进一步研究...我将发布结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-23
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 2018-10-12
  • 2019-08-21
  • 1970-01-01
相关资源
最近更新 更多