【发布时间】:2018-05-09 14:42:49
【问题描述】:
我从某个地方找到了这个程序,并试图理解它。
这一行:s[j++] = s[i]; 是导致崩溃的原因。我的理解是,至少程序第一次不应该崩溃,因为 j 稍后会增加。第一次 j 和 i 的值为 0。
所以,这就像 s[0] = s[0];
为什么会崩溃?
#include <iostream>
using namespace std;
void squeeze(char a[], char c);
int main()
{
squeeze("qwiert", 'i');
return 0;
}
void squeeze(char s[], char c)
{
int i, j;
for (i = j = 0; s[i] != '\0'; i++)
{
if (s[i] != c)
{
std::cout << "\ni: " << s[i];
s[j++] = s[i];
std::cout << "\nj: " << s[j];
std::cout << "\nj : " << j;
exit(0);
}
}
s[j] = '\0';
}
输出:
i: q
此后程序崩溃。
我已经把exit语句停止了那个指向segfault的程序。
【问题讨论】:
-
为s保留的地址空间可以写保护吗?因为在 main() 中它被定义为一个常量,编译器可以将它放入特殊的内存区域。但这只是猜测。
-
是的,这就是原因。 @KillPinguin
-
编译时收到以下警告:“ISO C++ 禁止将字符串常量转换为 'char*' [-Wwrite-strings]”。一些编译器会直接拒绝这个(技术上都应该)并给你一个错误。该程序将在编译时出现警告,但警告意味着有些东西不太符合 kosher 的规定,并且该程序很可能不会按照您预期的方式运行。
-
@user4581301,标准中实际上没有任何内容要求实现完全拒绝 UB。虽然这可能是一个很好的功能,但您可能应该区分什么是必需和什么是有用的。
-
@paxdiablo 字符串文字到
char*的转换在 C++11 中被正式禁止,但是,是的,我不知道 Aquarius_Girl 编译的标准是什么。
标签: c++ arrays segmentation-fault