如何解决如果出现 k 次,则删除字符串中的相邻重复项---堆缓冲区溢出错误
给定一个字符串 s
和一个整数 k
,k
重复删除包括从 k
中选择 s
个相邻且相等的字母并删除它们,导致被删除子串的左侧和右侧连接在一起。
我们反复在 k
上进行 s
次重复删除,直到无法再删除为止。
我尝试了以下代码,它在一台机器(机器 1)上工作,并在另一台机器(机器 2)中引发错误。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int sizeOfString(char * s)
{
int count=0;
while(s[count]!='\0')
count ++;
return count;
}
int getSubString(char *source,char *target,int from,int to)
{
int i=0,j=0;
for(i=from,j=0;i<=to;i++,j++){
target[j]=source[i];
}
target[j]='\0';
return 0;
}
char * removeDuplicates(char * s,int k){
int sizeString=sizeOfString(s);
char *stringS= (char*)calloc(sizeString,sizeof(char));
strcpy( stringS,s);
int occuranceCount=1;
int i=1;
for (i=1;i<sizeString;i++)
{
if (s[i]==s[i-1])
{
occuranceCount++;
}
else{
occuranceCount=1;
}
if (occuranceCount==k)
{
char *firstPart=(char*)calloc(i-k,sizeof(char));
getSubString(s,firstPart,i-k);
char *secondPart=(char*)calloc(sizeString,secondPart,i+1,sizeString-1);
strcat(firstPart,secondPart);
strcpy(s,firstPart);
free (firstPart);
free(secondPart);
removeDuplicates(s,k);
}
}
free(stringS);
return s;
}
int main()
{
char word[]="adbbbcccb";
printf("after truncating the string is %s\n",removeDuplicates(word,3));
return 0;
}
机器 1 输出:
after truncating the string is adb
...Program finished with exit code 0
Press ENTER to exit console.
机器 2 在 PC、BP 和 SPthe error is shown in the attached picture 的特定值处引发堆缓冲区溢出错误。我做错了什么?
解决方法
对于初学者来说,不清楚为什么您编写自己的函数 sizeOfString
而不是使用标准字符串函数 strlen
而另一方面您正在使用其他标准字符串函数,例如 {{1} } 或 strcpy
。
要么你应该在任何需要标准字符串函数的地方使用它,要么你不应该完全使用标准字符串函数。
使用动态分配内存的方法效率低下且不安全。
例如这个代码片段
strcat
导致内存溢出,因为没有为源字符串的终止零分配空间。
该功能存在错误。例如,假设 int sizeString=sizeOfString(s);
char *stringS= (char*)calloc(sizeString,sizeof(char));
strcpy( stringS,s);
等于 k
并且字符串以两个相等的字符开头。在这种情况下,您有(请参阅此代码片段)
2
int occuranceCount=1;
int i=1;
for (i=1;i<sizeString;i++)
{
if (s[i]==s[i-1])
{
occuranceCount++;
}
else{
occuranceCount=1;
}
if (occuranceCount==k)
{
char *firstPart=(char*)calloc(i-k,sizeof(char));
//...
等于 i
,1
递增并变为等于 2,因为字符串的第二个字符等于字符串的第一个字符。因此,occuranceCount
调用中的表达式 i - k
等于 calloc
,这会导致分配的内存大小无效,从而导致未定义的行为。
或者例如在这个声明之后
-1
以及函数本身的递归调用
strcpy(s,firstPart);
字符串removeDuplicates(s,k);
的长度和使用的索引s
变得无效。所以for循环依次无效。
我可以建议以下演示程序中显示的以下非递归函数。该函数不是基于使用标准 C 字符串函数,也不动态分配内存。
i
程序输出为
#include <stdio.h>
char * removeDuplicates( char *s,size_t n )
{
if ( n == 1 )
{
*s = '\0';
}
else if ( n != 0 )
{
char *p = s;
for ( char *q = s; *q; )
{
char c = *q;
size_t i = 1;
while ( i < n && *++q == c ) ++i;
if ( i != n )
{
if ( p != q - i )
{
while ( i ) *p++ = *( q - i-- );
}
else
{
p += i;
}
}
else
{
++q;
}
}
*p = '\0';
}
return s;
}
int main(void)
{
char s0[] = "112223333";
puts( removeDuplicates( s0,0 ) );
char s1[] = "112223333";
puts( removeDuplicates( s1,1 ) );
char s2[] = "112223333";
puts( removeDuplicates( s2,2 ) );
char s3[] = "adbbbcccb";
puts( removeDuplicates( s3,3 ) );
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。