C++ 在C+中以数组的负索引访问内存+;不归还垃圾
我编写了以下程序来搜索给定字符串数组中的特定字符串。我在搜索函数中犯了一个错误,并编写了I--而不是I++C++ 在C+中以数组的负索引访问内存+;不归还垃圾,c++,arrays,c++11,memory,C++,Arrays,C++11,Memory,我编写了以下程序来搜索给定字符串数组中的特定字符串。我在搜索函数中犯了一个错误,并编写了I--而不是I++ #include <iostream> #include <string> using namespace std; int search(string S[], int pos, string s) { for(int i=0; i<pos; i--) { cout << i << " : " <<
#include <iostream>
#include <string>
using namespace std;
int search(string S[], int pos, string s)
{
for(int i=0; i<pos; i--) {
cout << i << " : " << S[i] << "\n";
if (S[i] == s) {
cout << "Inside Return ->\n";
cout << i << " / " << S[i] << " / " << s << "\n";
return i;
}
}
return -1;
}
int main()
{
string S[] = {"abc", "def", "pqr", "xyz"};
string s = "def";
cout << search(S,2,s) << "\n";
return 0;
}
PS-我正在使用g++(Ubuntu 7.3.0-27ubuntu1~18.04)7.3.0
编辑-我知道g++不检查边界,但我被S[-1]的值始终与S相同的事实所吸引。我想知道是否有任何可能的理论来解释这种越界访问是未定义的行为 未定义的行为读取不是“垃圾”或“segfault”,而是字面上的任何东西。读取可能会导致时间旅行,并使程序早期的代码表现出不同的行为。程序的行为,从开始到结束,无论何时发生任何未定义的行为,都完全被C++标准所指定。 在本例中,NaiveAssembly和ABI告诉您,运行时“堆栈”上的参数位于函数的参数附近 因此,将代码简单地重写到程序集中会导致从参数到函数的负索引读取 但是,大量完全无害的、通用的和安全的机器代码替代解释,从内联开始,远离内联,使这种情况不会发生
当在没有LTO的情况下编译或在动态库边界上编译时,您可以对编译器发布的ABI将用于调用有一定的信心;其他地方的任何假设都是非常糟糕的。如果您在编译时没有LTO,并且依赖LTO,那么现在意味着您必须从现在开始审核代码的每一个构建,直到永远,否则,很长一段时间后就会出现一个没有明显原因的错误。是的,这是一个重复。但也很有趣,因为您可能访问函数调用堆栈。。。请阅读@AlgirdasPreidžius链接问题的答案,了解未定义行为的解释:)@Quentin一个人的垃圾是另一个人的财富!“我知道g++不检查边界”这不仅仅是g++。没有编译器被强制检查边界,通过C++标准。“但是我很好奇S[-1]的值总是和S一样。”未定义的行为是未定义的。在您使用的这个特定编译器版本中也可能是这样,但它也可以在您更新编译器时格式化您的硬盘驱动器。请尝试打印每个字符串的地址及其值。我怀疑
s
位于内存中s[0]
的“左侧”。
0 : abc
-1 : def
Inside Return ->
-1 / def / def