以下程序会输入a sentence
,an old word
和new word
目标是replace all the occurrences old word with the new word
。
int countOccurrence(char* sen,char* word) //counts occurrences of old word
{
int count=0,i,k,len1,len2;
len1=strlen(sen);
len2=strlen(word);
for(i=0;i<len1-len2+1;)
{
k=0;
while(word[k] && sen[k+i]==word[k])
k++;
if(k==len2 && sen[k+i]==' ' || sen[k+i]=='\0')
{
count++;
i+=len2;
}
else ++i;
}
return count;
}
void replace(char* sen,char* oldword,char* newword)
{
int count,len1,len2,len3,i,top=-1,k;
char *ptr;
count=countOccurrence(sen,oldword);
if(!count) return;
len1=strlen(sen);
len2=strlen(oldword);
len3=strlen(newword);
ptr=(char*)malloc(sizeof(len1+count*(len3-len2)+1));
for(i=0;i<len1-len2+1;)
{
k=0;
while(oldword[k] && sen[k+i]==oldword[k])
k++;
if(k==len2 && sen[k+i]==' ' || sen[k+i]=='\0')
{
for(k=0;newword[k];++k)
ptr[++top]=newword[k];
i+=len2;
}
else
{
ptr[++top]=sen[i];
++i;
}
}
ptr[++top]='\0';
strcpy(sen,ptr);
free(ptr); <-------------------------------
}
执行后,我收到的错误为:http://ideone.com/mh3X1
*** glibc detected *** ./prog: free(): invalid next size (fast): 0x08f49008 ***
======= Backtrace: =========
/lib/libc.so.6[0xb75fcfd4]
/lib/libc.so.6(cfree+0x9c)[0xb75fe87c]
./prog[0x8048834]
./prog[0x80484c1]
======= Memory map: ========
当我评论声明时,程序有效:
free(ptr);
当我尝试释放()堆上分配的内存时,为什么我收到错误?
答案 0 :(得分:5)
你搞砸了malloc
保存的内部信息,并在下一次操作时检测到它(这是免费的)。原因如下:
ptr=(char*)malloc(sizeof(len1+count*(len3-len2)+1));
^^^^^^
在此上下文中,sizeof评估平台上整数的大小:几乎肯定小于您想要的。因此,当您写入ptr
时,在4或8个字节后,您将走出分配的区域,所有投注都将关闭。
旁注:这主要是品味问题,但您应该停止投射malloc
返回的值。
答案 1 :(得分:4)
这条线是可疑的:
ptr=(char*)malloc(sizeof(len1+count*(len3-len2)+1));
您不希望sizeof
出现。
答案 2 :(得分:1)
这是堆损坏的典型案例。在程序的某个地方,你正在编写一些动态数组的边界,覆盖free
所需的数据,以了解它应该做什么。
尝试运行valgrind:
valgrind --leak-check=full ./your_program
正如其他人所说,你没有为ptr
正确分配内存。我能看到的另一个问题是strcpy(sen,ptr);
。最终结果的大小可能比句子大,因此您也会越过sen
的边界。