我来自 Java,目前正在学习 C++。我正在使用 Stroustrup 的 Progamming Principles and Practice of Using C++。我现在正在使用 vector 。在第 117 页上,他说访问 vector 的不存在元素将导致运行时错误(在 Java 中相同,索引越界)。我正在使用 MinGW 编译器,当我编译并运行这段代码时:
#include <iostream>
#include <cstdio>
#include <vector>
int main()
{
std::vector<int> v(6);
v[8] = 10;
std::cout << v[8];
return 0;
}
它给我作为输出 10。更有趣的是,如果我不修改不存在的 vector 元素(我只是打印它期望运行时错误或至少一个默认值)它会打印一些大整数。那么...是 Stroustrup 错了,还是 GCC 有一些奇怪的编译 C++ 的方法?
最佳答案
这本书有点含糊。这与其说是“运行时错误”,不如说是在运行时出现的未定义行为。这意味着任何事情都可能发生。但错误完全是你,而不是程序执行,事实上,甚至谈论具有未定义行为的程序的执行是不可能的,也是不明智的。
与 Java 完全不同,C++ 中没有任何东西可以保护您免受编程错误的侵害。
正如@sftrabbit 所说,std::vector 有一个替代接口(interface),.at() ,它总是给出一个正确的程序(尽管它可能会抛出异常),因此是一个可以推理的程序。
让我用一个例子来重复这一点,因为我相信这是 C++ 的一个重要的基础方面。假设我们正在从用户那里读取一个整数:
int read_int()
{
std::cout << "Please enter a number: ";
int n;
return (std::cin >> n) ? n : 18;
}
现在考虑以下三个程序:
危险的:这个程序的正确性取决于用户的输入!它不一定不正确,但它不安全(到了我称之为损坏的程度)。
int main()
{
int n = read_int();
int k = read_int();
std::vector<int> v(n);
return v[k];
}
无条件正确:无论用户输入什么,我们都知道这个程序的行为。
int main() try
{
int n = read_int();
int k = read_int();
std::vector<int> v(n);
return v.at(k);
}
catch (...)
{
return 0;
}
理智的上面带有.at() 的版本很尴尬。最好检查并提供反馈。因为我们进行了动态检查,所以未经检查的 vector 访问实际上保证没问题。
int main()
{
int n = read_int();
if (n <= 0) { std::cout << "Bad container size!\n"; return 0; }
int k = read_int();
if (k < 0 || k >= n) { std::cout << "Bad index!\n"; return 0; }
std::vector<int> v(n);
return v[k];
}
(我们忽略了 vector 构造可能抛出自身异常的可能性。)
道德是 C++ 中的许多操作是不安全的并且只有条件正确,但是程序员应该提前进行必要的检查。语言不会为你做,所以你不用为此付出代价,但你必须记住去做。这个想法是你无论如何都需要处理错误情况,所以与其在库或语言级别强制执行昂贵的、非特定的操作,不如将责任留给程序员,他们可以更好地集成检查进入无论如何都需要编写的代码。
如果我想开玩笑的话,我会将这种方法与 Python 进行对比,Python 允许您编写令人难以置信的简短 和正确 程序,而无需任何用户编写的错误处理根本。不利的一面是,任何试图使用这样一个程序的尝试,只要稍微偏离了程序员的意图,就会给您留下一个非特定的、难以阅读的异常和堆栈跟踪,并且几乎没有什么指导你应该做得更好。您不必编写任何错误处理程序,而且通常最终不会编写任何错误处理程序。 (我无法将 C++ 与 Java 进行比较,因为虽然 Java 通常安全,但我还没有看到简短 Java 程序。)
关于C++: vector 边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14015632/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t
我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc
我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat
这是我在ChefRecipe中的一blockRuby:#ifdatadirdoesn'texist,moveoverthedefaultoneif!File.exist?("/vol/postgres/data")execute"mv/var/lib/postgresql/9.1/main/vol/postgres/data"end结果是:Executingmv/var/lib/postgresql/9.1/main/vol/postgres/datamv:inter-devicemovefailed:`/var/lib/postgresql/9.1/main'to`/vol/post
我已经开始使用RubyMine6。我正在处理Rails4、Ruby2.1.1项目。我无法找到如何使用Pow作为服务器调试到RubyMine。你能给我指明正确的方向吗? 最佳答案 我能够使用远程调试从RubyMine进行调试。我正在使用RubyMine6、Rails3、Ruby2.1.1。首先创建一个.powenv文件并添加:exportRUBY_DEBUG_PORT=1234exportPOW_WORKERS=1将以下gem添加到您的Gemfile:gem'ruby-debug-ide'gem'debase'创建一个新的初始化器st