做一个任务,我必须实现一些功能。其中一个函数是检查字符串是否为回文。
#include <stdio.h>
#include <stdlib.h>
char string[] = "cameron";
char string2[] = "mah";
char palindrome[] = "madam";
char notPalindrome[] = "music";
int removeChar(char *str1, char * str2, char c){
int length = 0;
for (int i = 0; str1[i] != '\0'; i++){
length++;
}
for (int i = 0; i <= length; i++){
if (str1[i] == c){
str2[i] = '*';
}
else {
str2[i] = str1[i];
}
}
for (int i = 0; i<= length; i++){
printf("%c", str2[i]);
}
}
int isPalindrome(char *str){
int length = 0;
for (int i = 0; str[i] != '\0'; i++){
length++;
}
int j = length - 1;
int reversible = 0;
for (int i = 0; i < j; i++){
if (str[i] != str[j]){
reversible++;
break;
}
j--;
}
if (reversible > 0){
printf("\nString is not a palindrome\n");
}
else {
printf("\nString is replaceable\n");
}
}
int main(){
removeChar(string, string2, 'm');
isPalindrome(palindrome);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行这段代码,它说该字符串不是回文的时候是应该的,但为什么它,如果我改变isPalindrome(palindrome);到isPalindrome("madam");它的工作原理。
还有为什么如果我注释掉//removeChar(string, string2, 'm');, isPalindrome()会正常工作。
你有一个缓冲区溢出。removeChar隐含地假定str2与 的长度相同str1。所以当你运行这个时:
for (int i = 0; i <= length; i++){
if (str1[i] == c){
str2[i] = '*';
}
else {
str2[i] = str1[i];
}
}
Run Code Online (Sandbox Code Playgroud)
随着str1存在"cameron"和str2存在"mah",你越过边界str2并进入存储的记忆palindrome。所以,你运行后removeChar(string, string2, 'm');,将char[]是用来装mah\0现持有ca*e和char[]那个用来装madam\0现在持有ron\0m\0。显然,"ron"不是回文。之后尝试打印字符串的值,您removeChar(string, string2, 'm');应该会看到此操作。
允许您在没有分段错误的情况下执行此操作的唯一原因是,顺便说一下,您使用的是char[]代替char*。您可能更喜欢在数组上使用指针,这样这样的事情就不会无声无息地失败。