如果通过指针访问这个函数,为什么会导致访问冲突?
Why does this function cause an Access Violation if accessed via a pointer?
我有以下代码:
void Aurora64::Messaging::SendConsoleMessageToPlayer(int channelId , const char *msg)
{
CGameRules *pGameRules = new CGameRules;
pGameRules->SendTextMessage(eTextMessageConsole, msg, eRMI_ToClientChannel, channelId);
delete(pGameRules);
}
通过指针pGameRules
访问另一个类中的函数,但是该函数在调用时导致程序崩溃。
此代码位于另一个文件的Aurora64
类中。
当将以下代码放入指针的类CGameRules
(在其内部执行的函数中)时,程序崩溃:
CGameRules *pGameRules = new CGameRules;
pGameRules->SendTextMessage(eTextMessageConsole, "$4test", eRMI_ToClientChannel, channelId);
delete(pGameRules);
这是在测试Aurora64
类文件中的某些内容是否导致崩溃(它不是)。
然而,当放置在同一个类中时,程序可以完美地工作,没有崩溃:
SendTextMessage(eTextMessageConsole, "$4test", eRMI_ToClientChannel, channelId);
除了指针之外,代码在功能上是相同的(使用相同的输入值)。
注释掉delete
调用不起作用。
调用栈为:
Aurora64.dll!IGameObject::GetEntityId() Line 301 C+Aurora64.dll!IGameObject::InvokeRMI_Primitive<CGameRules::MethodInfo_ClTextMessage,
CGameRules::TextMessageParams>(const CGameRules::MethodInfo_ClTextMessage method,
const CGameRules::TextMessageParams
& params, unsigned int where,
IRMIListener * pListener, int userId, int channel, unsigned int dependentId)
Line 281 C++
Aurora64.dll!IGameObject::InvokeRMI<CGameRules::MethodInfo_ClTextMessage,
CGameRules::TextMessageParams>(const
CGameRules::MethodInfo_ClTextMessage method, const CGameRules::TextMessageParams
& params, unsigned int where, int channel)
Line 275 C++
Aurora64.dll!CGameRules::SendTextMessage(ETextMessageType type, const char * msg, unsigned int
to, int channelId, const char * p0, const char * p1, const char * p2,
const char * p3)
Line 3075 C++
Aurora64.dll!CGameRules::OnClientConnect(int channelId, bool isReset) Line 596 C++
我不明白为什么它会崩溃…从技术上讲,代码应该可以工作,因为调用的是完全相同的函数,输入也是完全相同的。
我有GitHub上的源代码应该是必需的(它没有Aurora64
类,因为它是基于GitHub的另一个项目,但源代码没有改变)。这也有可能是调试它的危机战争游戏和专用服务器包将需要,使它更难的人在这里调试。
这个问题可能是我遗漏了一些非常明显的东西。
我做错了什么?
SendTextMessage
方法:
int CScriptBind_GameRules::SendTextMessage(IFunctionHandler *pH, int type, const char *msg)
{
CGameRules *pGameRules=GetGameRules(pH);
if (!pGameRules)
return pH->EndFunction();
int to=eRMI_ToAllClients;
int channelId=-1;
if (pH->GetParamCount()>2)
pH->GetParam(3, to);
if (pH->GetParamCount()>3)
{
if (pH->GetParamType(4)==svtPointer)
{
ScriptHandle playerId;
pH->GetParam(4, playerId);
channelId=pGameRules->GetChannelId((EntityId)playerId.n);
}
else if (pH->GetParamType(4)==svtNumber)
pH->GetParam(4, channelId);
}
if (pH->GetParamCount()>4)
{
string p[4];
for (int i=0;i<pH->GetParamCount()-4;i++)
{
switch(pH->GetParamType(5+i))
{
case svtPointer:
{
ScriptHandle sh;
pH->GetParam(5+i, sh);
if (IEntity *pEntity=gEnv->pEntitySystem->GetEntity((EntityId)sh.n))
p[i]=pEntity->GetName();
}
break;
default:
{
ScriptAnyValue value;
pH->GetParamAny(5+i, value);
switch(value.GetVarType())
{
case svtNumber:
p[i].Format("%g", value.number);
break;
case svtString:
p[i]=value.str;
break;
case svtBool:
p[i]=value.b?"true":"false";
break;
default:
break;
}
}
break;
}
}
pGameRules->SendTextMessage((ETextMessageType)type, msg, to, channelId,
p[0].empty()?0:p[0].c_str(),
p[1].empty()?0:p[1].c_str(),
p[2].empty()?0:p[2].c_str(),
p[3].empty()?0:p[3].c_str()
);
}
else
pGameRules->SendTextMessage((ETextMessageType)type, msg, to, channelId);
return pH->EndFunction();
}
我忽略了特定项目的对象系统,正如molbdnilo所解释的:
也许你不能仅仅创建一个CGameRules实例然后开始使用它-它必须正确设置。很可能只有一个在程序中,在启动时创建,你应该使用它。
我在项目四周寻找这样一个对象,我找到了:
CGameRules *pGameRules=g_pGame->GetGameRules();
相关文章:
- 写入位置0x0000000C时发生访问冲突
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 链表中写入访问冲突的未知原因
- 为什么创建进程 API 调用会导致内存访问冲突?
- 为什么我的数组说部分通过写入访问冲突?
- 为什么我的布尔函数返回 true 会导致读取访问冲突?
- C++ 抛出读取访问冲突错误,但我不确定为什么。平铺滑块益智游戏
- 为什么未初始化的指针会导致接近 0 的 mem 访问冲突
- 为什么我的顶点缓冲区对象出现访问冲突错误?
- 为什么会出现访问冲突运行时错误
- 为什么此代码会导致访问冲突
- 为什么访问冲突异常不能被 捕获.NET4.0.
- 为什么我在用SDL2_ttf填充文本时出现访问冲突错误
- 为什么我会收到访问冲突运行时错误
- 为什么此代码会引发访问冲突异常
- C++,为什么在修改新分配的对象后会出现访问冲突
- 为什么在锁定weak_ptr时出现访问冲突?
- 为什么在使用ReadFile()函数时会出现访问冲突?
- 为什么即使是 16 字节对齐的地址也会导致_mm_load_si128导致访问冲突
- 如果通过指针访问这个函数,为什么会导致访问冲突?