Valgrind连接字符串的函数中的内存泄漏

问题描述

我使用valgrind查找内存泄漏。我写了一个函数“ prefix_to_string”来连接任意两个字符串,但是当我使用命令时

valgrind --leak-check=full ./helloworld

它说我有很多内存泄漏。我真的不知道在哪里,为什么。我问一个朋友为什么会发生这种情况,他说这是两次执行malloc,函数执行1次,函数执行1次,但是我不知道该如何处理该泄漏,因为我认为我需要来执行那些内存请求。 这是Valgrind给我的输出:

==9078== Memcheck,a memory error detector
==9078== Copyright (C) 2002-2015,and GNU GPL'd,by Julian Seward et al.
==9078== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==9078== Command: ./holamundo
==9078==
==9078== error calling PR_SET_PTRACER,vgdb might block
150:62
bye
==9078==
==9078== HEAP SUMMARY:
==9078==     in use at exit: 63 bytes in 4 blocks
==9078==   total heap usage: 5 allocs,1 frees,575 bytes allocated
==9078==
==9078== 5 bytes in 1 blocks are definitely lost in loss record 1 of 4
==9078==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9078==    by 0x400740: prefix_to_string (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==    by 0x4008AC: main (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==
==9078== 7 bytes in 1 blocks are definitely lost in loss record 2 of 4
==9078==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9078==    by 0x400740: prefix_to_string (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==    by 0x4008C3: main (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==
==9078== 8 bytes in 1 blocks are definitely lost in loss record 3 of 4
==9078==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9078==    by 0x400740: prefix_to_string (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==    by 0x4008D8: main (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==
==9078== 43 bytes in 1 blocks are definitely lost in loss record 4 of 4
==9078==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9078==    by 0x400897: main (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==
==9078== LEAK SUMMARY:
==9078==    definitely lost: 63 bytes in 4 blocks
==9078==    indirectly lost: 0 bytes in 0 blocks
==9078==      possibly lost: 0 bytes in 0 blocks
==9078==    still reachable: 0 bytes in 0 blocks
==9078==         suppressed: 0 bytes in 0 blocks
==9078==
==9078== For counts of detected and suppressed errors,rerun with: -v
==9078== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)

这是我的代码的主要部分,因此您可以通过这种方式重现问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <math.h>

char* prefix_to_string(char* first_string,char* second_string){
    char* name = first_string;
    char* extension = second_string;    
    char* name_with_extension;
    name_with_extension = malloc(strlen(name)*(sizeof(char))+strlen(extension)*(sizeof(char))+1); /* make space for the new string (should check the return value ...) */
    strcpy(name_with_extension,name); /* copy name into the new var */
    strcat(name_with_extension,extension); /* add the extension */
    return name_with_extension;
}

static char *itoa_simple_helper(char *dest,int i) {
  if (i <= -10) {
    dest = itoa_simple_helper(dest,i/10);
  }
  *dest++ = '0' - i%10;
  return dest;
}

char *itoa_simple(char *dest,int i) {
  char *s = dest;
  if (i < 0) {
    *s++ = '-';
  } else {
    i = -i;
  }
  *itoa_simple_helper(s,i) = '\0';
  return dest;
}

int main(int argc,char *argv[]) {

int idx = 150;
int id = 62;
char str_idx[20];
char str_id[20];
itoa_simple( str_idx,idx);
itoa_simple( str_id,id);
char *text_to_write;
text_to_write = malloc(2+sizeof(str_id)+sizeof(str_idx)+1);
text_to_write = prefix_to_string(str_idx,":");
text_to_write = prefix_to_string(text_to_write,str_id);
text_to_write = prefix_to_string(text_to_write,"\n");

printf("%s",text_to_write);
printf("bye\n");
free(text_to_write);




return 1;
}

解决方法

您没有足够频繁地调用free() -如果您不调用free()来释放每个单独的内存分配,就无法避免内存泄漏。并且您在text_to_write中对main()的重复分配意味着您只丢弃了指向某些已分配内存的指针,因此无法释放已分配的内存。 C需要对内存管理进行无休止的关心。

您有:

char *text_to_write;
text_to_write = malloc(2+sizeof(str_id)+sizeof(str_idx)+1);
// This assignment throws away the memory from the previous malloc
text_to_write = prefix_to_string(str_idx,":");
// This assignment throws away the memory from the previous prefix_to_string
text_to_write = prefix_to_string(text_to_write,str_id);
// This assignment also throws away the memory from the previous prefix_to_string
text_to_write = prefix_to_string(text_to_write,"\n");

printf("%s",text_to_write);
printf("bye\n");
// Calling free here only releases the last allocation from prefix_to_string
free(text_to_write);

您需要更多类似的东西:

char *part1 = prefix_to_string(str_idx,":");
char *part2 = prefix_to_string(part1,str_id);
char *part3 = prefix_to_string(part2,part3);
printf("bye\n");

free(part1);
free(part2);
free(part3);

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...