0

下面的程序接受输入a sentence,an old word和 a 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);    

见这里:http: //ideone.com/fr34H

为什么当我尝试释放()堆上分配的内存时出现错误?

4

3 回答 3

5

您弄乱了保存的内部信息malloc,它在下一次操作时检测到它(这是免费的)。原因如下:

ptr=(char*)malloc(sizeof(len1+count*(len3-len2)+1));
                  ^^^^^^

在这种情况下, sizeof 评估为您平台上整数的大小:几乎肯定小于您想要的。因此,当您写入ptr4 或 8 个字节后,您将走出分配的区域,并且所有赌注都已关闭。


旁注:这在很大程度上是一个品味问题,但您可能应该停止转换malloc.

于 2012-07-26T13:47:23.343 回答
4

这条线是可疑的:

ptr=(char*)malloc(sizeof(len1+count*(len3-len2)+1));

你不想sizeof在那里。

于 2012-07-26T13:47:33.257 回答
1

这是堆损坏的典型案例。在您的程序中的某个地方,您正在写出一些动态数组的边界,覆盖free了理解它应该做什么所必需的数据。

尝试运行valgrind

valgrind --leak-check=full ./your_program

正如其他人所提到的,您没有为ptr. 我可以看到的另一个问题是strcpy(sen,ptr);. 最终结果的大小可能比句子大,因此您sen也超出了范围。

于 2012-07-26T13:45:58.663 回答