在我提出问题之前,我会仔细阅读所有使用的内容......
我在这里创建了一个char
指针数组,我在一个函数中使用了该数组
char *TShirtsText[] = { "Black", "Yellow", "Blue" };
ModelChanger->AddVariantItem("R* T-Shirts", TShirtsText[0], -1, 0, 2, 1, DevShirt, (bool*)true);
现在我有了这个功能,请注意optionstext
// Add a variant item to the menu
void GTAVMenu::AddVariantItem(char *displayText, char *optionstext, float var, float min, float max, float changeby, GTAVMenuCallback functionCallback, void *functionParameters) {
GTAVMenuItem menuItem;
// Set menu type
menuItem.menuItemType = MENU_TYPE_VARIANT;
// Add variant text to item text
char newDisplayText[32];
if (functionParameters == NULL)
sprintf_s(newDisplayText, sizeof(newDisplayText), "%s: < %g >", displayText, var);
else
sprintf_s(newDisplayText, sizeof(newDisplayText), "%s: < Not Set >", displayText);
// Copy menu item text
strcpy_s(menuItem.itemText, 32, newDisplayText);
// Function callback
menuItem.functionCallback = functionCallback;
// No display callback
menuItem.displayCallback = NULL;
// Sub menu
menuItem.subMenu = NULL;
// Function params
menuItem.functionParameters = functionParameters;
// Menu item toggling
menuItem.itemToggleable = false;
menuItem.itemToggled = false;
// Keep memory of displayText, optionstext, var, min, max, changeby
menuItem.vartext = displayText;
if (functionParameters != NULL) menuItem.optionstext = optionstext;
menuItem.var = var;
menuItem.min = min;
menuItem.max = max;
menuItem.changeby = changeby;
// Add our menu item
menuItems->push_back(menuItem);
}
这是一个代码示例,我按下按钮,这是大致发生的事情,请注意optionstext
switch(menuItem->menuItemType)
{
case MENU_TYPE_VARIANT:
{
if (menuItem->var <= menuItem->min)
menuItem->var = menuItem->max;
else
//menuItem->var--;
menuItem->var -= menuItem->changeby;
selectedNum = menuItem->var;
play_sound_frontend(0, "NAV_UP_DOWN", "HUD_FRONTEND_DEFAULT_SOUNDSET");
// Add variant text to item text
char newDisplayText[32];
if (menuItem->functionParameters == NULL)
sprintf_s(newDisplayText, sizeof(newDisplayText), "%s: < %g >", menuItem->vartext, menuItem->var);
else
sprintf_s(newDisplayText, sizeof(newDisplayText), "%s: < %s >", menuItem->vartext, menuItem->optionstext);
// Copy menu item text
strcpy_s(menuItem->itemText, 32, newDisplayText);
// Calling function - never used to be here
menuItem->functionCallback(selectedMenuItem, menuIndexStack, menuItem->itemText, menuItem->functionParameters);
break;
}
}
这就是问题出现的地方。所以,我正在使用一个char指针数组,我正在使用该数组中的第一个元素,你可以从第一段代码中看到。在最后一段代码中,其中一个sprintf_s
将menuItem->optionstext
放入newDisplayText
。在输出中,当我按下左按钮时,sprintf_s
使用char指针数组的最后一个元素,如果我按下控制器上的右按钮,它会将其更改为下一个元素。
为什么在我没有说明要复制哪个元素时,它会将其更改为下一个元素?为什么程序允许我这样做,特别是当我在函数中使用的是数组中的一个元素时?
答案 0 :(得分:0)
您只为字符串保留32个字节:
char newDisplayText[32];
但是你将完整的32个字符放入其中,因此没有空间可以关闭'\0'
。
因此,任何访问都会溢出,读取或写入内存中接下来发生的任何事情。这通常会产生各种有趣和疯狂的错误。
您需要声明char newDisplayText[33];
有32个字符的空间。