user-0 提问: 5. 最长回文子串

回复:
user: user-0
content: 引用 9 楼 zangfong 的回复:不好意思，我仔细看了代码，用不同的编译器调试了一下，确实是有问题的。你说的两个问题都是用指针模拟数组时引起的访问越界。 free(intAry)这个报错是因为申请空间不够，既然后面的for循环中i都取到(strlen(s) * 2 + 1)了，那你申请的intAry空间自然是不够了，最后访问越界了。因此要跟上面的newStr一样(strlen(s) * 2 + 2) intAry = (int *)malloc(sizeof(int) * (strlen(s) * 2 + 2));  至于你说的本地运行能够出bb，提交之后是空串，我觉得是下面的访问越界引起的： 你的代码中for循环里面的while循环中mvp--;这句在执行的时候，也一样越界了，你可以自己单步调试一下看看，就明白了         while(*mvp == *mvq)         {             len+=1;             mvp--;             mvq++;         } 因此这里需要加一个限制条件，以下的测试代码供参考 #include<stdio.h> #include<string.h> #include<stdlib.h>  char* longestPalindrome(char* s) {     char *newStr = NULL;     char *newStrStart = NULL;     char *mvp = NULL;     char *mvq = NULL;     int  *intAry = NULL;     int   len = 0, maxlen = 0, pos = 1;      if(strlen(s) < 2)         return s;      /*set new str  [aba] => [#a#b#a#] */     newStr = (char*)malloc(sizeof(char) * (strlen(s)*2 +2));     memset(newStr,0,sizeof(newStr));     mvp = s;     mvq = newStr;     while(*mvp != '\0')     {         *mvq = '#';         *(mvq+1) = *mvp;          mvp++;         mvq = mvq + 2;     }     *mvq = '#';     *(mvq+1) = '\0';      /*cal len[i]*/     intAry = (int *)malloc(sizeof(int) * (strlen(s) * 2 + 2));     memset(intAry,0,sizeof(intAry));     for(int i = 0 ; i < (strlen(s) * 2 + 2); i++)     {         len = 1;         intAry[i] = 1;         mvp = newStr + i - 1;         mvq = newStr + i + 1;         if(mvp < newStr || mvq >= (newStr + strlen(newStr)))         {             continue;         }          while( (*mvp == *mvq) &&(mvp - newStr >= 0))         {             len+=1;             mvp--;             mvq++;         }          intAry[i] = len;          if(len > maxlen)         {             maxlen = len;             pos = i;         }     }      /*cal start pos*/     if(pos % 2 == 0)     {         newStrStart = s + pos/2 - maxlen/2;     }else     {         newStrStart = s + pos/2 - (maxlen/2 - 1);     }      free(newStr);     free(intAry);  //2.为什么这个free会出错     newStr = (char*)malloc(sizeof(char) * maxlen);     memcpy(newStr, newStrStart, maxlen - 1 );     newStr[maxlen-1] = '\0';      return newStr; }  int main() {     char str[] = "bb";     printf("%s\n",longestPalindrome(str));     return 0; } [quote=引用 8 楼 qimi_and_softkitty 的回复:]  哎?是我编译工具有问题吗。。。 上传的时候显示input为"bb"时结果不对。。。不懂。。。 [/quote]   谢谢谢谢。通过了呢。 确实是 while(*mvp == *mvq)         {             len+=1;             mvp--;             mvq++;         } 这里越界了。我默认为越界他们取值会不等然后退出。没有考虑到同时越界的话取值会相等。  但是 intAry = (int *)malloc(sizeof(int) * (strlen(s) * 2 + 1)); for(int i = 0 ; i < (strlen(s) * 2 + 1); i++) 这个是没有越界的哦~  总而言之，多谢了。

user: user-1
content: 不好意思，我仔细看了代码，用不同的编译器调试了一下，确实是有问题的。你说的两个问题都是用指针模拟数组时引起的访问越界。 free(intAry)这个报错是因为申请空间不够，既然后面的for循环中i都取到(strlen(s) * 2 + 1)了，那你申请的intAry空间自然是不够了，最后访问越界了。因此要跟上面的newStr一样(strlen(s) * 2 + 2) intAry = (int *)malloc(sizeof(int) * (strlen(s) * 2 + 2));  至于你说的本地运行能够出bb，提交之后是空串，我觉得是下面的访问越界引起的： 你的代码中for循环里面的while循环中mvp--;这句在执行的时候，也一样越界了，你可以自己单步调试一下看看，就明白了         while(*mvp == *mvq)         {             len+=1;             mvp--;             mvq++;         } 因此这里需要加一个限制条件，以下的测试代码供参考 #include<stdio.h> #include<string.h> #include<stdlib.h>  char* longestPalindrome(char* s) {     char *newStr = NULL;     char *newStrStart = NULL;     char *mvp = NULL;     char *mvq = NULL;     int  *intAry = NULL;     int   len = 0, maxlen = 0, pos = 1;      if(strlen(s) < 2)         return s;      /*set new str  [aba] => [#a#b#a#] */     newStr = (char*)malloc(sizeof(char) * (strlen(s)*2 +2));     memset(newStr,0,sizeof(newStr));     mvp = s;     mvq = newStr;     while(*mvp != '\0')     {         *mvq = '#';         *(mvq+1) = *mvp;          mvp++;         mvq = mvq + 2;     }     *mvq = '#';     *(mvq+1) = '\0';      /*cal len[i]*/     intAry = (int *)malloc(sizeof(int) * (strlen(s) * 2 + 2));     memset(intAry,0,sizeof(intAry));     for(int i = 0 ; i < (strlen(s) * 2 + 2); i++)     {         len = 1;         intAry[i] = 1;         mvp = newStr + i - 1;         mvq = newStr + i + 1;         if(mvp < newStr || mvq >= (newStr + strlen(newStr)))         {             continue;         }          while( (*mvp == *mvq) &&(mvp - newStr >= 0))         {             len+=1;             mvp--;             mvq++;         }          intAry[i] = len;          if(len > maxlen)         {             maxlen = len;             pos = i;         }     }      /*cal start pos*/     if(pos % 2 == 0)     {         newStrStart = s + pos/2 - maxlen/2;     }else     {         newStrStart = s + pos/2 - (maxlen/2 - 1);     }      free(newStr);     free(intAry);  //2.为什么这个free会出错     newStr = (char*)malloc(sizeof(char) * maxlen);     memcpy(newStr, newStrStart, maxlen - 1 );     newStr[maxlen-1] = '\0';      return newStr; }  int main() {     char str[] = "bb";     printf("%s\n",longestPalindrome(str));     return 0; } 引用 8 楼 qimi_and_softkitty 的回复:哎?是我编译工具有问题吗。。。 上传的时候显示input为"bb"时结果不对。。。不懂。。。

user: user-0
content: 引用 7 楼 zangfong 的回复:我用codeblocks运行没错 呀貌似#include<stdio.h> #include<string.h> #include<stdlib.h>  char* longestPalindrome(char* s) {     char *newStr = NULL;     char *newStrStart = NULL;     char *mvp = NULL;     char *mvq = NULL;     int  *intAry = NULL;     int   len = 0, maxlen = 0, pos = 1;      if(strlen(s) < 2)         return s;      /*set new str  [aba] => [#a#b#a#] */     newStr = (char*)malloc(sizeof(char) * (strlen(s)*2 +2));     mvp = s;     mvq = newStr;     while(*mvp != '\0')     {         *mvq = '#';         *(mvq+1) = *mvp;          mvp++;         mvq = mvq + 2;     }     *mvq = '#';     *(mvq+1) = '\0';      /*cal len[i]*/     intAry = (int *)malloc(sizeof(int) * (strlen(s) * 2 + 1));      for(int i = 0 ; i < (strlen(s) * 2 + 1); i++)     {         len = 1;         intAry[i] = 1;         mvp = newStr + i - 1;         mvq = newStr + i + 1;         if(mvp < newStr || mvq >= (newStr + strlen(newStr)))         {             continue;         }          while(*mvp == *mvq)         {             len+=1;             mvp--;             mvq++;         }          intAry[i] = len;          if(len > maxlen)         {             maxlen = len;             pos = i;         }     }      /*cal start pos*/     if(pos % 2 == 0)     {         newStrStart = s + pos/2 - maxlen/2;     }else     {         newStrStart = s + pos/2 - (maxlen/2 - 1);     }      free(newStr);     free(intAry);  //2.为什么这个free会出错     newStr = (char*)malloc(sizeof(char) * maxlen);     memcpy(newStr, newStrStart, maxlen - 1 );     newStr[maxlen-1] = '\0';      return newStr; }  int main() {     char str[] = "abcdabcba";     //char *res=longestPalindrome(str);     printf("%s\n",longestPalindrome(str));     return 0; } 哎?是我编译工具有问题吗。。。 上传的时候显示input为"bb"时结果不对。。。不懂。。。

user: user-1
content: 我用codeblocks运行没错 呀貌似#include<stdio.h> #include<string.h> #include<stdlib.h>  char* longestPalindrome(char* s) {     char *newStr = NULL;     char *newStrStart = NULL;     char *mvp = NULL;     char *mvq = NULL;     int  *intAry = NULL;     int   len = 0, maxlen = 0, pos = 1;      if(strlen(s) < 2)         return s;      /*set new str  [aba] => [#a#b#a#] */     newStr = (char*)malloc(sizeof(char) * (strlen(s)*2 +2));     mvp = s;     mvq = newStr;     while(*mvp != '\0')     {         *mvq = '#';         *(mvq+1) = *mvp;          mvp++;         mvq = mvq + 2;     }     *mvq = '#';     *(mvq+1) = '\0';      /*cal len[i]*/     intAry = (int *)malloc(sizeof(int) * (strlen(s) * 2 + 1));      for(int i = 0 ; i < (strlen(s) * 2 + 1); i++)     {         len = 1;         intAry[i] = 1;         mvp = newStr + i - 1;         mvq = newStr + i + 1;         if(mvp < newStr || mvq >= (newStr + strlen(newStr)))         {             continue;         }          while(*mvp == *mvq)         {             len+=1;             mvp--;             mvq++;         }          intAry[i] = len;          if(len > maxlen)         {             maxlen = len;             pos = i;         }     }      /*cal start pos*/     if(pos % 2 == 0)     {         newStrStart = s + pos/2 - maxlen/2;     }else     {         newStrStart = s + pos/2 - (maxlen/2 - 1);     }      free(newStr);     free(intAry);  //2.为什么这个free会出错     newStr = (char*)malloc(sizeof(char) * maxlen);     memcpy(newStr, newStrStart, maxlen - 1 );     newStr[maxlen-1] = '\0';      return newStr; }  int main() {     char str[] = "abcdabcba";     //char *res=longestPalindrome(str);     printf("%s\n",longestPalindrome(str));     return 0; }

user: user-2
content: 看来是我想错呢，抱歉

user: user-0
content: 引用 2 楼 user-2 的回复:newStrStart = s + pos/2 - maxlen/2;你这行代码有什么用？你赋值给newstrstart的都是数字吧。  后面这里。newstrstart被用来指向回文起点~

user: user-0
content: 引用 3 楼 user-2 的回复:抱歉看错呢，应该是pos和maxlen的值与s指向的地址想加超出s的范围newStrStart=s+pos/2-maxlen/2以上只是我的猜测  没有呢。我有debug哦~

user: user-2
content: 抱歉看错呢，应该是pos和maxlen的值与s指向的地址想加超出s的范围newStrStart=s+pos/2-maxlen/2以上只是我的猜测

user: user-2
content: newStrStart = s + pos/2 - maxlen/2;你这行代码有什么用？你赋值给newstrstart的都是数字吧。

user: user-2
content: 你的newStr字符指针为什么会传会空指针是因为你在传回去之前就已经释放掉呢