You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++几乎回文程序isPalindrome调用语句未执行问题求助

问题现象

编写判断几乎回文(允许最多删除一个字符使得字符串成为回文)的C++程序时,疑似语句r = isPalindrome(str, p[0], p[1]-1);未执行,p、q对应的isPalindrome函数调用看似正常运行,程序仅打印p和q的取值后异常退出,无法定位执行流程问题,完整原始代码如下:

#include <iostream>
#include<vector>
using namespace std;

int arr[2];


int* isPalindrome(string &s, int i, int j){

    int sz = s.length();

    if(i==j) return NULL;

    while(i<j){

        if(s[i] == s[j]){
            i++;
            j--;
        }

        else{
            arr[0] = i;
            arr[1] = j;
            return arr;
        }
    }

    return NULL;
}


int main()
{

   string s = "abcdefdba", str;
   int *p, *q, *r;

   // removes any additional character or spaces and make lower-case
   for(int i=0; i<s.length();i++){
    if(s[i] >= 65 && s[i]<=90) str.push_back(s[i]+32);
    if((s[i] >=97 && s[i]<=122) || (s[i]>=48 && s[i]<=57)) str.push_back(s[i]);
   }

    p = isPalindrome(str, 0, str.length()-1);

    cout<<"pointer p: "<<p[0]<<p[1]<<endl;

    if(p==NULL) cout<<"true";

    else{
         q = isPalindrome(str, p[0]+1, p[1]);

         r = isPalindrome(str, p[0], p[1]-1); // not getting executed
        }


    cout<<"pointer q: "<<q[0]<<q[1]<<endl;
    cout<<"pointer r: "<<r[0]<<r[1]<<endl;

    if(q==NULL || r==NULL) cout<<"true";
    else cout<<"false";


    return 0;

}
根因分析

你误以为r的赋值行未执行,实际是程序存在空指针/野指针解引用的致命问题,在执行到r相关的打印逻辑前就已经触发段错误异常退出,核心问题点如下:

  • 所有指针解引用操作前没有做非空判断:只要isPalindrome返回NULL(代表子串是回文),后续直接访问p[0]/q[0]/r[0]就会访问非法内存,触发段错误直接终止程序。比如当删除左字符后的子串是回文时,q被赋值为NULL,执行到打印q的语句时就会崩溃,根本走不到后续r的打印逻辑,看起来就像r的赋值行没跑。
  • 全局数组共享内存的逻辑错误:所有非NULL的isPalindrome返回值都指向同一个全局数组arr,后续调用会覆盖之前写入的索引值,导致p、q、r指向的内容被意外篡改,逻辑完全不符合预期。
  • 指针未初始化:p、q、r定义时没有初始化为NULL,如果原串本身是回文(p==NULL),不会进入else块给q、r赋值,后续访问q、r属于野指针访问,程序行为完全不可控。
  • 冗余判断:isPalindrome里if(i==j) return NULL;是多余代码,i==j时循环条件i<j不成立,本来就会走到函数末尾返回NULL,不会影响逻辑但属于无效代码。
  • 预处理逻辑可读性差:用ASCII硬编码判断字符类型,且两个if没有做互斥,虽然当前场景不会重复插入字符,但后续修改很容易引入bug。
修复方案

直接重构isPalindrome的返回值为bool类型即可,不需要用全局数组传索引,从根源避免空指针和内存共享问题,修复后代码如下:

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

// 直接返回子串s[i..j]是否为回文
bool isPalindrome(string &s, int i, int j){
    while(i < j){
        if(s[i] != s[j]) return false;
        i++;
        j--;
    }
    return true;
}

int main()
{
    string s = "abcdefdba", str;
    // 预处理字符串:转小写,只保留字母和数字
    for(int i=0; i<s.length();i++){
        if(isalpha(s[i])){
            str.push_back(tolower(s[i]));
        }else if(isdigit(s[i])){
            str.push_back(s[i]);
        }
    }

    int left = 0, right = str.length() - 1;
    bool res = true;
    while(left < right){
        if(str[left] != str[right]){
            // 遇到不匹配位置,判断删左字符或者删右字符后是否为回文
            res = isPalindrome(str, left+1, right) || isPalindrome(str, left, right-1);
            break;
        }
        left++;
        right--;
    }

    cout << (res ? "true" : "false") << endl;
    return 0;
}

内容的提问来源于stack exchange,提问作者Mohan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:31:11