2012-07-26 2 views
0

Le programme ci-dessous prend en entrée a sentence, an old word et new word.
L'objectif est de replace all the occurrences old word with the new word.Erreur lors de la libération() d'un fragment de mémoire

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); <------------------------------- 
} 

Après l'exécution, je reçois l'erreur: 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: ========  

Les programmes de travaux lorsque je commente la déclaration:

free(ptr);  

voir ici: http://ideone.com/fr34H

Pourquoi je reçois une erreur quand j'essaie de libérer() la mémoire allouée sur le tas?

+0

est "sen" assez grand pour recevoir le résultat final de strcpy()? – wildplasser

Répondre

5

Vous avez foiré les informations internes conservées par malloc et il les a détectées lors des opérations suivantes (qui étaient libres). Voici la raison:

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

Dans ce contexte, le sizeof évalue à la taille de l'entier sur votre plate-forme: presque sûrement moins que ce que vous voulez. Ainsi, lorsque vous écrivez à ptr, après 4 ou 8 octets, vous sortez de la zone allouée et tous les paris sont désactivés.


Side note: il est en grande partie une question de goût, mais vous devriez probablement arrêter la coulée de la valeur retournée par malloc.

1

Ceci est un cas typique de corruption de tas. Quelque part dans votre programme, vous écrivez hors des limites d'un tableau dynamique, écrasant les données nécessaires pour free pour comprendre ce qu'il devrait faire.

Essayez d'exécuter valgrind:

valgrind --leak-check=full ./your_program 

Comme d'autres l'ont mentionné, vous n'avez pas correctement la mémoire allouée pour ptr. Un autre problème que je peux voir est strcpy(sen,ptr);. La taille du résultat final peut être plus grande que la phrase, donc vous allez aussi sur les limites de sen.

4

Cette ligne est suspect:

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

Vous ne voulez pas sizeof là.

Questions connexes