当引入参数时,从指针调用成员函数的 C++ 调用内存访问冲突

Posted

技术标签:

【中文标题】当引入参数时,从指针调用成员函数的 C++ 调用内存访问冲突【英文标题】:C++ calling a member function from a pointer is calling memory access violations when arguments are introduced 【发布时间】:2013-03-04 19:15:44 【问题描述】:

我正在使用 Winsock2 编写服务器。接收到的所有数据都是字符串形式。我有一个字符串解析器,它可以从以字符串形式给出的方法签名中提取方法名称和参数。因此 AddNewMember(arg1,arg2) 被拆分为一个名为 signature 的字符串,其中包含 AddNewMember 和一个包含 arg1 和 arg2 元素的字符串向量。这工作正常。为了使这些消息有意义,我有一个字符串到成员函数指针的映射,所有函数都采用相同的参数向量 args。这是我的 ServerControl 课程中的地图:

//from header
map<string, string (ServerControl::*)(vector<string>)> functionMap;

//this on init creates all entries to function map
functionMap["AddNewMember"] = &ServerControl::AddNewMemberFunc;
functionMap["GetMember"] = &ServerControl::GetMemberFunc;
functionMap["RemoveMember"] = &ServerControl::RemoveMemberFunc;

...etc

然后,一旦传入的消息被解析成它的部分,下面的代码就会访问映射以获取成员函数指针。

if (functionMap.find( signature ) != functionMap.end()) 

     return (this->*functionMap[message])(arguments); 

再一次,签名部分是“AddNewMethod”,参数是在 () 之间传递的参数向量。

如果参数向量为空,这将按预期工作,但即使一旦将参数添加到向量中,当代码到达此行并尝试调用成员函数时,我都会遇到内存访问冲突。我试过这个,参数是vector&lt;string&gt;* 和普通的vector&lt;string&gt;。我很困惑。

我才真正开始在这个项目上使用函数指针,所以我不是专业人士。任何帮助将不胜感激!谢谢

【问题讨论】:

【参考方案1】:

您正在使用signature 搜索地图,然后使用message 从地图中检索成员指针。如果signaturemessage 不是同一个值,您将不会得到您期望的指针,如果message 值在映射中尚不存在,甚至可能是NULL 指针。检索指针时,您需要再次使用signature。更好的是,由于您已经执行了一次搜索,您应该使用搜索结果而不是调用 [] 运算符再次执行相同的搜索。

试试这个:

typedef string (ServerControl::*VectorArgMember)(vector<string>);
map<string, VectorArgMember> functionMap;

.

map<string, VectorArgMember>::iterator i = functionMap.find( signature );
if (i != functionMap.end()) 

    VectorArgMember memberPtr = i->second;
    return (this->*memberPtr)(arguments); 

【讨论】:

哇。这么简单的错误。我已经连续工作了 10 个小时,我很累,所以只需要一双额外的眼睛。非常感谢

以上是关于当引入参数时,从指针调用成员函数的 C++ 调用内存访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

当参数之一是指针数组时,如何从 C# 调用 C++ DLL

C++ 当子类的方法和父类的方法重名时...

C++ CreateThread函数如何传递this指针作为参数

C++中函数参数以及Lambda 函数与表达式

C++之静态

在 C++ 中调用指向成员函数的指针时出错