输入大小为 1 的字符串时出现分段错误
Segmentation Fault on input of string of size 1
当我将大小为 1 的字符串作为输入传递时,出现分段错误(核心已转储)。我试着寻找原因但我找不到任何原因,我被要求调试我的程序。通过调试,我意识到它在读取大小为 1 的字符串时会抛出分段错误。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
ll t,x,y;
string s;
cin>>t;
while(t--){
cin>>s;
int tilt=0;
for(int i=s.length()-1,j=0;i>=s.length()/2;i--,j++){
if(s[i]!=s[j]){
tilt = s[i]>s[j]?-1:1;
s[i]=s[j];
}
}
if(tilt==-1 || tilt==0){
if(s.length()%2==0){
y=1;x=s.length()/2-1;
while(y!=0 && x>=0){
if(s[x]=='9'){
s[x]='0';
}else{
s[x] += 1;
y=0;
}
x--;
}
if(y==0){
for(int i=0;i<s.length()/2;i++){
cout<<s[i];
}
for(int i=s.length()/2-1;i>=0;i--){
cout<<s[i];
}
cout<<endl;
}else{
cout<<1;
for(int i=0;i<s.length()/2;i++){
cout<<s[i];
}
for(int i=s.length()/2-2;i>=0;i--){
cout<<s[i];
}
cout<<1<<endl;
}
}else{
y=1;x=s.length()/2;
while(y!=0 && x>=0){
if(s[x]=='9'){
s[x]='0';
}else{
s[x] += 1;
y=0;
}
x--;
}
if(y==0){
for(int i=0;i<s.length()/2;i++){
cout<<s[i];
}
for(int i=s.length()/2;i>=0;i--){
cout<<s[i];
}
cout<<endl;
}else{
cout<<1;
for(int i=0;i<s.length()/2;i++){
cout<<s[i];
}
for(int i=s.length()/2-1;i>=0;i--){
cout<<s[i];
}
cout<<1<<endl;
}
}
}else{
cout<<s<<endl;
}
}
return 0;
}
输入:
1个
11
输出:
22
输入:
1个
1个
输出:
错误
这里
for(int i=s.length()-1,j=0;i>=s.length()/2;i--,j++){
当 s
的大小为 1 时,s.length()/2
是一个 unsigned 值为 0 的数量。当比较一个整数和一个无符号数时,整数是在比较之前转换为无符号。检查无符号值是否 >= 0 始终为真,因此这是一个无限循环。这就是它崩溃的原因。
我希望您的编译器能就 signed/unsigned 比较的危险向您发出警告。
这是修复此特定循环的一种方法,但我猜您在代码的其他地方也有类似的问题。
for (size_t i = s.length(), j = 0; i > s.length()/2; ++j) {
--i;
if (s[i] != s[j]) {
tilt = s[i] > s[j] ? -1 : 1;
s[i] = s[j];
}
}
一些建议
- 对索引变量使用
size_t
。
- 当向后循环时要非常小心终止条件,我这样做的方法是使变量比它需要的大一个,并在循环开始而不是结束时递减它。这样你就可以与
>
而不是 >=
进行比较,从而避免你的代码出现的问题。
- 尝试在代码中使用一些空格。它使包括您自己在内的每个人都更容易阅读。
当我将大小为 1 的字符串作为输入传递时,出现分段错误(核心已转储)。我试着寻找原因但我找不到任何原因,我被要求调试我的程序。通过调试,我意识到它在读取大小为 1 的字符串时会抛出分段错误。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
ll t,x,y;
string s;
cin>>t;
while(t--){
cin>>s;
int tilt=0;
for(int i=s.length()-1,j=0;i>=s.length()/2;i--,j++){
if(s[i]!=s[j]){
tilt = s[i]>s[j]?-1:1;
s[i]=s[j];
}
}
if(tilt==-1 || tilt==0){
if(s.length()%2==0){
y=1;x=s.length()/2-1;
while(y!=0 && x>=0){
if(s[x]=='9'){
s[x]='0';
}else{
s[x] += 1;
y=0;
}
x--;
}
if(y==0){
for(int i=0;i<s.length()/2;i++){
cout<<s[i];
}
for(int i=s.length()/2-1;i>=0;i--){
cout<<s[i];
}
cout<<endl;
}else{
cout<<1;
for(int i=0;i<s.length()/2;i++){
cout<<s[i];
}
for(int i=s.length()/2-2;i>=0;i--){
cout<<s[i];
}
cout<<1<<endl;
}
}else{
y=1;x=s.length()/2;
while(y!=0 && x>=0){
if(s[x]=='9'){
s[x]='0';
}else{
s[x] += 1;
y=0;
}
x--;
}
if(y==0){
for(int i=0;i<s.length()/2;i++){
cout<<s[i];
}
for(int i=s.length()/2;i>=0;i--){
cout<<s[i];
}
cout<<endl;
}else{
cout<<1;
for(int i=0;i<s.length()/2;i++){
cout<<s[i];
}
for(int i=s.length()/2-1;i>=0;i--){
cout<<s[i];
}
cout<<1<<endl;
}
}
}else{
cout<<s<<endl;
}
}
return 0;
}
输入: 1个 11 输出: 22
输入: 1个 1个 输出: 错误
这里
for(int i=s.length()-1,j=0;i>=s.length()/2;i--,j++){
当 s
的大小为 1 时,s.length()/2
是一个 unsigned 值为 0 的数量。当比较一个整数和一个无符号数时,整数是在比较之前转换为无符号。检查无符号值是否 >= 0 始终为真,因此这是一个无限循环。这就是它崩溃的原因。
我希望您的编译器能就 signed/unsigned 比较的危险向您发出警告。
这是修复此特定循环的一种方法,但我猜您在代码的其他地方也有类似的问题。
for (size_t i = s.length(), j = 0; i > s.length()/2; ++j) {
--i;
if (s[i] != s[j]) {
tilt = s[i] > s[j] ? -1 : 1;
s[i] = s[j];
}
}
一些建议
- 对索引变量使用
size_t
。 - 当向后循环时要非常小心终止条件,我这样做的方法是使变量比它需要的大一个,并在循环开始而不是结束时递减它。这样你就可以与
>
而不是>=
进行比较,从而避免你的代码出现的问题。 - 尝试在代码中使用一些空格。它使包括您自己在内的每个人都更容易阅读。