【问题标题】:C++ Memory Error when using if(condition) return: Unbelievable [closed]使用if(条件)返回时出现C ++内存错误:难以置信[关闭]
【发布时间】:2025-11-21 14:40:01
【问题描述】:

今天我写了一些有趣的代码,将整数转换为罗马数字。 完整的运行代码在这里:

#include <iostream>
#include <map>
#include <string>

using namespace std;

string arabic2roman(int i){
//if(i==0) return "ZERO";

map<int, string> m;
m.insert(pair<int,string>(0,"ZERO"));
m.insert(pair<int,string>(1,"I"));
m.insert(pair<int,string>(4,"IV"));
m.insert(pair<int,string>(5,"V"));
m.insert(pair<int,string>(9,"IX"));
m.insert(pair<int,string>(10,"X"));
m.insert(pair<int,string>(40,"XL"));
m.insert(pair<int,string>(50,"L"));
m.insert(pair<int,string>(90,"XC"));
m.insert(pair<int,string>(100,"C"));
m.insert(pair<int,string>(400,"CD"));
m.insert(pair<int,string>(500,"D"));
m.insert(pair<int,string>(900,"CM"));
m.insert(pair<int,string>(1000,"M"));

string roman;
map<int,string>::iterator iter;
for(iter=m.end();iter !=m.begin();iter--){
    while(i >=iter->first){
        roman+=iter->second;
        i-=iter->first;
    }
}
return roman;
}

int main(){
    int test=12345;
    cout << arabic2roman(test) << endl;
    return 0;
}

此代码现在在我的 Xcode 4.6.2 上运行良好。但是如果在第 8 行删除“//”之前 if(i==0) return "ZERO",在 Xcode 4.6.2 上,程序无限运行。 有人可以解释一下吗?谢谢!

【问题讨论】:

  • " 崩溃了,程序无休止地运行。"是哪一个?
  • 我已经编写了 15 年的 C++ 代码,是错误的制造者,而不是语言。
  • 因为您要取消引用 end() 迭代器? 3 年的 C++,你不知道你不应该这样做吗? :-)
  • @John 如果可以的话,我会投票两次。为我增加至少 +5 年...
  • 取消引用 end() 迭代器是未定义的行为。在实践中,这可能意味着您的程序最终可能会做各种非直觉的事情,而且很难(甚至毫无意义)推理出来。最好的办法是先解决这个问题,然后看看它是否有效。

标签: c++ if-statement error-handling return


【解决方案1】:

要以相反的顺序迭代,请使用 rbegin 和 rend:

for(iter=m.rbegin();iter !=m.rend(); ++iter){
    while(i >=iter->first){
        roman+=iter->second;
        i-=iter->first;
    }
}

http://en.cppreference.com/w/cpp/container/map/rbegin

【讨论】:

  • +1 好点,减少真正的问题
  • 哦,确实如此。我只复制-修改-粘贴原始代码。我知道 it++ 的行为:*.com/questions/24901/…
【解决方案2】:
for(iter=m.end();iter !=m.begin();iter--){
    while(i >=iter->first){
        roman+=iter->second;
        i-=iter->first;
    }
}

在第一次迭代中,您取消引用 m.end() 这是非法的。你不走运(不,不走运)它似乎与注释掉的那一行一起工作,因为它隐藏了这个主要错误。

像其他人一样做,从begin()开始,使用iter++

【讨论】:

  • rbegin()rend()
  • 耶稣! m.end() 是跟随实际元素的“理论”迭代器!难怪每个人都说取消引用!
  • 向前迭代意味着算法不起作用。您必须先减去最大值。