为什么这里不发生分段错误?
why doesn't segmentation fault occur here?
如果我没有定义我的向量的大小,则会发生分段错误,但这样,我的意思是我定义的大小低于我使用的大小,不会发生分段错误。但为什么?
它们有什么区别?
#include <iostream>
#include <string>
using namespace std;
#include <vector>
int main()
{
vector <string> a(2);
a[0]="hello world";
a[2]="maryam";
cout << a[0] << a[2];
return 0;
}
未定义的行为(这是您在使用 operator[]
读取或写入超出向量末尾时所做的事情)确切地 未定义。
对于大小为 2 的情况,它可能很容易崩溃,但似乎适用于大小为 0 的情况。
或者两者都可以在播放时格式化您的存储设备maniacal_laughter.mp3
。
未定义的行为对结果没有限制,建议您避开。
[] 运算符没有范围检查。 []运算符用于根据偏移值和“基”地址直接访问内存地址。
根据您的示例,
a[0], a[2]
0 和 2 是偏移值,“基”地址将是数组的地址,由向量指向。
如果要进行范围检查,请使用:
a.at(0), a.at(2)
C++ 有一个概念 undefined behavior. Accessing a vector out-of-bounds is a typical example of undefined behavior (because vector::operator[]
不执行边界检查)。关于程序的结果,没有什么有意义的东西可以说。
但是要解释可能发生的事情...
A vector
是一个 class
,通常包含指向堆分配数组的 指针 及其 大小 (“容量”)。
空向量具有空指针值。通常 立即 取消引用空指针会导致段错误,因为在地址 0 没有分配虚拟内存区域。
另一方面,容量为 2
的向量指向大小为 2
的数组。写过去通常是可能的,您将简单地覆盖恰好位于该数组之后之后的堆内存。这称为 heap buffer overflow。在一个简单的程序中,它可能看起来工作正常。但是在一个更大的程序中,代码后面的某个地方不会发生任何好事。
如果我没有定义我的向量的大小,则会发生分段错误,但这样,我的意思是我定义的大小低于我使用的大小,不会发生分段错误。但为什么? 它们有什么区别?
#include <iostream>
#include <string>
using namespace std;
#include <vector>
int main()
{
vector <string> a(2);
a[0]="hello world";
a[2]="maryam";
cout << a[0] << a[2];
return 0;
}
未定义的行为(这是您在使用 operator[]
读取或写入超出向量末尾时所做的事情)确切地 未定义。
对于大小为 2 的情况,它可能很容易崩溃,但似乎适用于大小为 0 的情况。
或者两者都可以在播放时格式化您的存储设备maniacal_laughter.mp3
。
未定义的行为对结果没有限制,建议您避开。
[] 运算符没有范围检查。 []运算符用于根据偏移值和“基”地址直接访问内存地址。 根据您的示例,
a[0], a[2]
0 和 2 是偏移值,“基”地址将是数组的地址,由向量指向。
如果要进行范围检查,请使用:
a.at(0), a.at(2)
C++ 有一个概念 undefined behavior. Accessing a vector out-of-bounds is a typical example of undefined behavior (because vector::operator[]
不执行边界检查)。关于程序的结果,没有什么有意义的东西可以说。
但是要解释可能发生的事情...
A vector
是一个 class
,通常包含指向堆分配数组的 指针 及其 大小 (“容量”)。
空向量具有空指针值。通常 立即 取消引用空指针会导致段错误,因为在地址 0 没有分配虚拟内存区域。
另一方面,容量为 2
的向量指向大小为 2
的数组。写过去通常是可能的,您将简单地覆盖恰好位于该数组之后之后的堆内存。这称为 heap buffer overflow。在一个简单的程序中,它可能看起来工作正常。但是在一个更大的程序中,代码后面的某个地方不会发生任何好事。