2015-12-22 2 views
1

Я пытаюсь вернуть указатель из функции и использовать возврат в другой функции, но я получаю утечку памяти.
Контрольный код, который я написал и обнаружил с утечкой памяти с помощью CPPCheck.Утечка памяти в C и C++ Код

######################################################################## 

# include <stdio.h> 
# include <malloc.h> 
# include <string.h> 

char* replace (char* st, char* word, char *replaceWith); 
int main (void) 
{ 
    char str[] = "Hello how are ## and what are ## doing ?"; 
    char word[]="##"; 
    char replaceWith[]="you"; 
    printf("%s",replace(str,word,replaceWith)); 
    getchar(); 
    return 0; 
} 

char* replace(char* st,char* word,char *replaceWith) 
{ 
int i = 0; 
char *sr,*s,*ret; 
int oldlen; 
int count = 0; 
int newlen; 
int stlen; 
s=(char *)malloc(strlen(st) + 1); 
strcpy(s, st); 
oldlen=strlen(word); 
newlen=strlen(replaceWith); 
for (i = 0; s[i]! = '\0';) 
{ 
    if(memcmp(&s[i], word, oldlen) == 0) 
    { 
     count++; 
     i+=oldlen; 
    } 

    else 
    { 
     i++; 
    } 
} 
sr= (char *) malloc (i+1+count*(newlen-oldlen)); 
ret = (char *) malloc (i+1+count*(newlen-oldlen)); 
ret=sr; 
while(*s) 
{ 
    if(memcmp(s, word, oldlen) == 0) 
    { 
     memcpy(sr, replaceWith, newlen); 
     s+ = oldlen; 
     sr+ = newlen; 
    } 
    else 
    { 
     *sr++ = *s++; 
    } 
} 

*sr = '\0'; 
return ret; 
} 
+1

Вы должны вызвать функцию free() для каждого указателя, выделенного malloc. – Sandy

+0

Я пытался позвонить бесплатно. Я могу позвонить бесплатно для sr и s, насколько я понимаю, но когда я вызываю сбой кода и как на «ret», я не могу назвать бесплатный метод замещения, который я пытался связать с ответственностью за вызывающий контекст. Тем не менее он падает. –

+0

сохранить возвращаемое значение функции replace в переменной, а затем вызывать свободную от основной функции. – Sandy

ответ

0

Попробуйте это

#include<stdio.h> 
#include<malloc.h> 
#include<string.h> 

char* replace (char* st, char* word, char *replaceWith); 

int main (void) 

{ 

    char str[] = "Hello how are ## and what are ## doing ?"; 

    char word[]="##"; 

    char replaceWith[]="you"; 

    char * ret = replace(str,word,replaceWith); 
    printf("%s",ret); 
    free(ret); //freeing the allocated memory 
    getchar(); 

    return 0; 
} 

char* replace(char* st,char* word,char *replaceWith) 
{ 

int i = 0; 

char *sr,*s,*ret, *temps; 

int oldlen; 

int count = 0; 

int newlen; 

int stlen; 

s=(char *)malloc(strlen(st) + 1); 
temps = s; // storing the address of s in a temp location 
strcpy(s, st); 

oldlen=strlen(word); 

newlen=strlen(replaceWith); 

for (i = 0; s[i]!= '\0';) 

{ 

    if(memcmp(&s[i], word, oldlen) == 0) 
    { 

     count++; 

     i+=oldlen; 

    } 

    else 
    { 
     i++; 
    } 

} 
sr= (char *) malloc (i+1+count*(newlen-oldlen)); 

ret=sr; 

while(*s) 
{ 
    if(memcmp(s, word, oldlen) == 0) 
    { 
     memcpy(sr, replaceWith, newlen); 

     s += oldlen; 

     sr += newlen; 

    } 
    else 
    { 

     *sr++ = *s++; 

    } 
} 

*sr = '\0'; 
free(temps); // freeing the memory allocated for s 
return ret; 

} 
+0

Спасибо !!! Работа без утечки памяти и сбоя. Но я не совсем понимаю, что вы скопировали s в temps и освободили только темп. Так почему бы не s и sr не быть свободным .. Извините, я немного слаб в проблемах с утечкой указателя и памяти –

+0

while (* s) {...} - это условие истинно до s! = NULL. условие равно false, когда s == NULL.Именно по этой причине я храню данные в временном расположении. – Sandy

+0

Значит, вы просто освобождаете адрес, на который указывает s, используя бесплатные (temps). По той же причине я могу думать, что sr не может быть освобожден и должен быть освобожден в основной функции. Это означает, что местоположение, указанное sr, будет освобождено свободным вызовом (ret) в главном. Пожалуйста, исправьте меня, если ошибаетесь. –

0

Всегда свободный же счетчик с malloc.

  1. бесплатно s, С.Р. в конце замены,
  2. использовать возвращаемое значение замены вместо непосредственного использования на Printf
    и свободного возвращаемого значения (возвращение в отставке из замены), когда не требуется.
+0

При попытке сделать то же, что и предложенное вами. Я получаю сообщение вроде: Windows вызвала точку останова в ReplacingTheString.exe. Это может быть связано с повреждением кучи, что указывает на ошибку в файле ReplacingTheString.exe или в любой из загружаемых DLL-файлов. Это может быть связано с тем, что пользователь нажал F12, в то время как XXX.exe имеет фокус. Выходное окно может содержать больше диагностической информации. –

+0

в то время как (* с) { \t, если (== memcmp (с, слово, oldlen) 0) \t { \t \t тетсру (ср, ReplaceWith, newlen); \t \t s + = oldlen; \t \t sr + = newlen; \t} \t еще \t { \t \t * стерад ++ = * С ++; \t} } * sr = '\ 0'; свободен (ы); бесплатно (sr); –

0

я делать много экспериментов с утечкой памяти и тем я написал следующий код. Пожалуйста, прокомментируйте ее плюсы и минусы.

#include <stdio.h> 
#include <string.h> 
#include <malloc.h> 

// Prototype declaration of replaceAll function 
static char* replaceAll(char *pSource, char *pWord, char*pWith); 


///////////////////////////////////////////////////////////////////////////// 
// 
// NAME   :  main 
// 
// DESCRIPTION :  Implementation of main which invokes the replaceAll 
//      function and displays the output    
// 
// PARAMETERS  :  void 
// 
// RETURNED VALUE :  int 
// 
///////////////////////////////////////////////////////////////////////////// 

int main(void) 
{ 
    char *finalString = NULL;       // To save the base returned address 
    char srcString[] = "Hello how r you";    // Actual String 
    char pWord[] = "r";         // Word to be replaced 
    char pWith[] = "are";        // Word to be replaced with 

    printf("\n Before Calling the replaceAll function:"); 

    printf("%s",srcString); 

    printf("\n"); 

    finalString = replaceAll(srcString, pWord, pWith); //calling the replaceAll function 

    printf("\n After Calling the replaceAll function:"); 

    // Checking if NULL is returned 
    if(finalString != NULL) 
    { 
     //printing the string 

     printf("%s", finalString); 

    } 
    else 
    { 
     printf("\n Error: Blank String returned "); 
    } 

    return 0; 
} 

///////////////////////////////////////////////////////////////////////////// 
// 
// NAME   :  replaceAll 
// 
// DESCRIPTION :  Implementation of replaceAll function which replaces 
//      a word in given string with another word   
// 
// PARAMETERS  :  char * 
// 
// RETURNED VALUE :  char * 
// 
///////////////////////////////////////////////////////////////////////////// 

static char* replaceAll(char *pSource, char *pWord, char*pWith) 
{ 

    char *pSt = NULL;    // Pointer to the source String to avoid modifying the pSource 
    char *pTarget = NULL;   // Target pointer to be malloced 
    char *pTg = NULL;    // Pointer to the target string 

    int count;      // Counter 
    int nWord = strlen (pWord);  // length of the word which needs to be replaced 
    int nWith = strlen (pWith);  // length of the word with which the word needs to be replaced 

    static const char nullP = '\0'; // null character 

    int szTarget = 0; 

    // Assigning the base address of the pSource to a temporary and iterate through 

    for (pSt = pSource, count = 0; *pSt != nullP; pSt++) 
    { 
     // Count number of occurances of the Word in the String to calculate the length of the final string 
     if(memcmp(pSt, pWord, nWord) == 0) 
     { 
      count++; 
      pSt += nWord-1; 
     } 
    } 

    // Calculate the required target Size 
    szTarget = strlen (pSource) + count * (nWith - nWord) + sizeof (nullP); 

    // Allocate memory for the target string 

    pTarget = (char *)malloc(szTarget); 

    // Check if the malloc function returns sucessfully 

    if (pTarget != NULL) 
    { 
     // Copying the string with replacement 
     for (pTg = pTarget, pSt = pSource; *pSt != nullP;) 
     { 
      if(memcmp (pSt, pWord, nWord) == 0) 
      { 
       memcpy (pTg,pWith,nWith); 
       pSt += nWord; 
       pTg += nWith; 
      } 
      else 
      { 
       *pTg++ = *pSt++; 
      } 
     } 

     // Assigning NULL Character to the target string after copying 
     *pTg = '\0'; 
    } 
    return pTarget; 
}