这是我为带有在线检查系统的作业编写的代码。 适用于给定的示例和我自己的简短示例,但检查系统表示它运行不正确并由于信号 11 而结束。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string mn;
string x;
char y;
for(int i = 0; i < 2000; i++)
{
cin >> x;
if(x!="DELETE")
{
cin >> y;
if(x == "APPEND")
{
mn = mn + y;
}
else if(x == "CHANGE")
{
mn.pop_back();
mn = mn + y;
}
else if(x == "PUSH")
{
int p = mn.find(y);
if(mn[p] == 'Z')
{mn[p] = 'A';}
else
{mn[p] = char(int(mn[p]) + 1);}
}
}
else
{
int u;
cin >> u;
mn.pop_back();
}
}
cout << mn;
}
我试图尽快修复它,因为我不知道我怎么可能留下分配的内存。谢谢!
通过用循环替换 a.find() 来修复它,基本上以某种方式做同样的事情,但我仍然不明白为什么这个版本不起作用。
通过用循环替换 a.find() 来修复它,基本上以某种方式做同样的事情,但我仍然不明白为什么这个版本不起作用。
如果您发布了为您提供工作版本的循环替换,我可以解释为什么循环有效以及它与 string::find 操作有何不同。
每当使用可能导致边缘情况的函数时,您应该通过处理它们来保护您的代码,以避免错误或未定义的行为。
std::string::find
参考(https://en.cppreference.com/w/cpp/string/basic_string/find)说:for a non-empty substring, if pos >= size(), the function always returns npos.
if (std::string::npos == n)
npos
参考(https://en.cppreference.com/w/cpp/string/basic_string/npos)说:
static const size_type npos = -1;
This is a special value equal to the maximum value representable by the type size_type.
The exact meaning depends on context, but it is generally used either as end of string
indicator by the functions that expect a string index or as the error
indicator by the functions that return a string index.
std::string::pop_back
参考(https://en.cppreference.com/w/cpp/string/basic_string/pop_back)说:
The behavior is undefined if the string is empty.
即使您没有深入查看这些参考资料,您仍然可以尝试查找边缘情况并放入打印跟踪代码(或只是在调试器中工作)以了解代码为何以意外方式运行。
参见 https://www.ideone.com/RlZ0ee
有关如何添加打印跟踪语句的示例。它显示标准输入:
APPEND
c
APPEND
e
PUSH
c
PUSH
Z
DELETE
1
和标准输出(显示程序在处理其余输入之前停止):
i:0 APPEND:c mn: c
i:1 APPEND:e mn: ce
i:2 PUSH:c
i:2 PUSH:c mn: de
i:3 PUSH:Z
p == npos = -1 DANGER: ACCESSING MEMORY OUTSIDE OF STRING CHARS
i:3 PUSH:Z mn: de9C@�O�PUSHD �+a��@�O�@k��`�����������O�z
a�@�y�����#�@�O��y�yH5ܞy����
�O��A-a�Y�+a��@�O��@�O�JO�QO�bO�vO��O��O��O��O��O�!O�3����d@@8�*a� �@kNkN
����O��O���O�|1he�=�w~|)���<x86_64
此垃圾表明代码不再打印合法的 std::string。就像数组一样,我们通常不期望 array[-1] 是可以接受的;这同样适用于字符串。这是添加了跟踪语句的程序:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string mn;
string x;
char y;
for(int i = 0; i < 5; i++)
{
cin >> x;
if(x!="DELETE")
{
cin >> y;
if(x == "APPEND")
{
mn = mn + y;
cout << "i:"<< i << " " << x << ":" << y << " mn: " << mn << endl;
}
else if(x == "CHANGE")
{
mn.pop_back();
mn = mn + y;
cout << "i:"<< i << " " << x << ":" << y << " mn: " << mn << endl;
}
else if(x == "PUSH")
{
int p = mn.find(y);
cout << "i:"<< i << " " << x << ":" << y << endl;
if( p == string::npos)
{
cout << "p == npos = " << p << " DANGER: ACCESSING MEMORY OUTSIDE OF STRING CHARS" << endl;
}
if(mn[p] == 'Z') {
mn[p] = 'A';
}
else {
mn[p] = char(int(mn[p]) + 1);
}
cout << "i:"<< i << " " << x << ":" << y << " mn: " << mn << endl;
}
}
else
{
int u;
cin >> u;
mn.pop_back();
cout << "i:"<< i << " " << x << ":N/A" << " mn: " << mn << endl;
}
}
cout << mn;
}