调试断言失败,字符串下标超出范围

Posted

技术标签:

【中文标题】调试断言失败,字符串下标超出范围【英文标题】:Debug assertion failed, string subscript out of range 【发布时间】:2013-02-19 16:18:58 【问题描述】:

我正在尝试编写一个函数,该函数从列表框中获取数据,检索帐户名称,然后使用 SQL 更改帐户类型。但是,由于某种原因,当列表框项包含“fdsa\t\tdungeon master”但不包含“asdf\t\tuser”时,此代码可以正常工作。在后来的测试中,它以 'auser\t\tuser' 失败。消息框功能表明正在检索正确的数据。这可能是什么原因造成的?

void ChangeAccountType(HWND hwnd, std::string NewType)

using namespace std;
string strQuery;
string strAccountName;
string strBuffer;
int nIndex = SendMessage(GetDlgItem(hwnd, IDC_LIST1), LB_GETCURSEL, 0, 0);
SendMessage(GetDlgItem(hwnd, IDC_LIST1), LB_GETTEXT, (WPARAM)nIndex, (LPARAM)strBuffer.c_str());
MessageBox(hwnd, strBuffer.c_str(), "", NULL);
for(int iii = 0; strBuffer[iii] != '\t'; iii++)

    strAccountName += strBuffer[iii];
;
strQuery = "UPDATE account SET `account type` = \"" + NewType + "\" WHERE `User Name` = \"" + strAccountName + "\"";

错误似乎发生在 for 循环中的某处,因为它上方的消息框运行良好。任何建议将不胜感激。

【问题讨论】:

我认为你 100% 确定字符串中有一个 TAB? 是的,提交给listbox的字符串格式为“username + \t\t + accounttype”,listbox正确显示 我看不到您将strBuffer 设置为任何内容的任何地方,您可能忘记了一些代码吗? 没有人会提出使用std::string::c_str() 作为LPARAM~ to LB_GETTEXT` 是一点都不好?如果您没有使用C++11,此时您正在使用未定义的行为。即使使用C++11,也不要这样做这个 【参考方案1】:

string strBuffer 是一个空字符串,大小为0,在您尝试访问strBuffer[iii] 之前,您的代码中没有任何内容会改变它,iii 等于0。这将返回对初始化 char 的值的引用,即空终止字符。下一次,您访问位置 1,该位置超出范围,因此行为未定义。

我怀疑您正在篡改字符串的内部char 数组数据,从而导致未定义的行为。大概是您通过c_str() 尝试修改它的一个或多个函数。这本身会导致未定义的行为。您不能将std::stringc_str() 用作可写字符缓冲区。

来自 21.4.7.1 [string.accessors]const charT* c_str() const noexceptconst charT* data() const noexcept

要求:程序不得更改存储在字符数组中的任何值。

【讨论】:

那么为什么当我使用 'fdsa\t\tdungeonmaster' 值时它可以正常工作?这就是我开始使用 += 的原因,因为每次使用 strAccountName[iii] 都会失败。如果是这样,我将如何获取字符串的第一部分? @MatsPetersson 选项卡无关紧要,首先访问空字符串上的strBuffer[0] 为什么strBuffer[0]是一个空字符串,它应该包含'a'? 'a' 显示在 for 循环之前的消息框中 好的,非常感谢。对我来说仍然没有多大意义,为什么它会如此具体地中断,但如果我切换到 char[50],它就可以正常工作,所以问题基本上得到了解决。 当您需要一个需要修改的字符串缓冲区时,您不应该使用std::string::c_str()。在C++11 之前这样做是未定义的行为,而在C++11 这样做是不好的做法

以上是关于调试断言失败,字符串下标超出范围的主要内容,如果未能解决你的问题,请参考以下文章

调试断言失败(向量下标超出范围)

C++ 调试断言失败。向量下标超出范围

(opencv) 调试断言失败,向量下标超出范围

调试错误 - 向量下标超出范围 - PCL

如何在 Linux 上强制执行向量下标超出范围调试断言

unordered_map 在使用 [] 运算符时报告“向量下标超出范围”断言