gpt4 book ai didi

c - 尽管内存已被释放,Valgrind 仍检测到内存泄漏

转载 作者:太空宇宙 更新时间:2023-11-04 00:48:50 25 4
gpt4 key购买 nike

我有一个文件“a”,有 2000 个字符,只有字符“a”,没有空格。

然后我有这段代码,它通过循环运行,将其添加到缓冲区,如果达到限制最终重新分配,并在出现错误时释放 strBuffer 变量。

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

int main()
{
int maxS = 200;
int numericExpression;
int strLength;


char *strBuffer;
strBuffer = malloc(sizeof(char)*maxS+1);
if(strBuffer == NULL)
{
printf("Failed to allocate requested memory!\n");
free(strBuffer);
strLength = sizeof(strBuffer);
printf("Freed %d bytes of memory!\n", strLength);
exit(99);
}
else
{
numericExpression = sizeof(char)*maxS+1;
printf("Alocated: %d Bytes of memory.\n", numericExpression);
}

// while simulation

int fcv = -1;
int numEx;


// file opening simulation
FILE* fd = fopen("a", "r");


int c;
while((c=fgetc(fd) != EOF)) // condition to make sure we realloc only once
{
fcv++;
strBuffer[fcv] = c;
if(fcv == (maxS))
{
printf("Additional memory space required!\n");
int strlensize = strlen(strBuffer);
numEx = (sizeof(char)*(2*strlensize));


strBuffer = realloc(strBuffer, numEx);

if(strBuffer == NULL)
{
printf("Failed to allocate requested memory!\n");
strLength = sizeof(strBuffer);
free(strBuffer);
printf("Freed %d bytes of memory!\n", strLength);
exit(99);
}
else
{
maxS = numEx;
printf("Reallocation successful!\n");
printf("Alocated: %d Bytes of memory.\n", numEx);
}

}

}
strLength = sizeof(strBuffer);
free(strBuffer);
printf("Freed %d bytes of memory!\n", strLength);
}

问题是它最后告诉我,我只释放了 8 个字节的内存。我想这是因为 sizeof(strBuffer) 没有响应预期的大小。当我改用 strlen(strBuffer) 时,我只释放了 2001 个字节。

我想这可能只是打印出释放的字节数的问题。我可能做错了。所以也许我只是不知道我释放了多少字节。但是后来我尝试了 valgrind,它告诉我,我没有足够的自由,存在内存泄漏。但是在程序的每个分支中,我都可以释放 strBuffer 使用的内存。

当我通过 valgrind ("valgrind ./realloc") 运行它时,它告诉我:

==780== Memcheck, a memory error detector
==780== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==780== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==780== Command: ./realloc
==780==
Alocated: 201 Bytes of memory.
Additional memory space required!
==780== Invalid read of size 1
==780== at 0x4C2E0F4: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==780== by 0x400846: main (in /home/dan/Desktop/test_ifj/realloc)
==780== Address 0x51fd109 is 0 bytes after a block of size 201 alloc'd
==780== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==780== by 0x40078C: main (in /home/dan/Desktop/test_ifj/realloc)
==780==
Reallocation successful!
Alocated: 402 Bytes of memory.
==780== Invalid write of size 1
==780== at 0x400823: main (in /home/dan/Desktop/test_ifj/realloc)
==780== Address 0x51fd562 is 0 bytes after a block of size 402 alloc'd
==780== at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==780== by 0x400866: main (in /home/dan/Desktop/test_ifj/realloc)
==780==
Additional memory space required!
Reallocation successful!
Alocated: 806 Bytes of memory.
Additional memory space required!
==780== Conditional jump or move depends on uninitialised value(s)
==780== at 0x4C2E0F8: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==780== by 0x400846: main (in /home/dan/Desktop/test_ifj/realloc)
==780==
Reallocation successful!
Alocated: 804 Bytes of memory.
Freed 8 bytes of memory!
==780==
==780== HEAP SUMMARY:
==780== in use at exit: 568 bytes in 1 blocks
==780== total heap usage: 5 allocs, 4 frees, 2,781 bytes allocated
==780==
==780== LEAK SUMMARY:
==780== definitely lost: 0 bytes in 0 blocks
==780== indirectly lost: 0 bytes in 0 blocks
==780== possibly lost: 0 bytes in 0 blocks
==780== still reachable: 568 bytes in 1 blocks
==780== suppressed: 0 bytes in 0 blocks
==780== Rerun with --leak-check=full to see details of leaked memory
==780==
==780== For counts of detected and suppressed errors, rerun with: -v
==780== Use --track-origins=yes to see where uninitialised values come from
==780== ERROR SUMMARY: 1200 errors from 3 contexts (suppressed: 0 from 0)

如何正确释放分配的内存?所以不会造成内存泄漏?最终-我做错了吗,有更好的方法吗?感谢您的帮助。

问题更新

我听从了建议,在 1 个上下文中出现了 3 个错误。这就是我的代码现在的样子:

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

int main()
{
int maxS = 200;
int numericExpression;


char *strBuffer;
strBuffer = malloc((maxS+1));
if(strBuffer == NULL)
{
printf("Failed to allocate requested memory!\n");
printf("Freed %d bytes of memory!\n", maxS);
exit(99);
}
else
{
numericExpression = sizeof(char)*maxS+1;
printf("Alocated: %d Bytes of memory.\n", numericExpression);
}

// while simulation

int fcv = -1;
int numEx;


// file opening simulation
FILE* fd = fopen("a", "r");

if(fd == NULL)
{
printf("Error opening a file!\n");

if(strBuffer != NULL)
{free(strBuffer);}


exit(99);
}


int c;

char *tmpBuffer;
while((c=fgetc(fd)) != EOF) // condition to make sure we realloc only once
{
fcv++;
strBuffer[fcv] = c;

if(fcv == (maxS))
{
printf("Additional memory space required!\n");

numEx = ((2*fcv));


tmpBuffer = realloc(strBuffer, numEx);
if(!tmpBuffer)
{
free(strBuffer);
printf("Realloc() failed!\n");
exit(99);
}
else
{
strBuffer = tmpBuffer;
}


if(strBuffer == NULL)
{
printf("Failed to allocate requested memory!\n");
printf("Freed %d bytes of memory!\n", maxS); // well this is questionable, I think
exit(99);
}
else
{
maxS = numEx;
printf("Reallocation successful!\n");
printf("Alocated: %d Bytes of memory.\n", maxS);
}

}

}

free(strBuffer);fclose(fd); // ADDED, still errors occur

printf("Freed %d bytes of memory!\n", maxS);
}

通过相同的 valgrind 调用(“valgrind ./realloc”)我得到了这个:

==1213== Invalid write of size 1
==1213== at 0x4007FD: main (in /home/dan/Desktop/test_ifj/realloc)
==1213== Address 0x51fd560 is 0 bytes after a block of size 400 alloc'd
==1213== at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1213== by 0x400831: main (in /home/dan/Desktop/test_ifj/realloc)
==1213==
Additional memory space required!
Reallocation successful!
Alocated: 800 Bytes of memory.
Additional memory space required!
Reallocation successful!
Alocated: 1600 Bytes of memory.
Additional memory space required!
Reallocation successful!
Alocated: 3200 Bytes of memory.
Freed 3200 bytes of memory!
==1213==
==1213== HEAP SUMMARY:
==1213== in use at exit: 568 bytes in 1 blocks
==1213== total heap usage: 6 allocs, 5 frees, 6,769 bytes allocated
==1213==
==1213== LEAK SUMMARY:
==1213== definitely lost: 0 bytes in 0 blocks
==1213== indirectly lost: 0 bytes in 0 blocks
==1213== possibly lost: 0 bytes in 0 blocks
==1213== still reachable: 568 bytes in 1 blocks
==1213== suppressed: 0 bytes in 0 blocks
==1213== Rerun with --leak-check=full to see details of leaked memory
==1213==
==1213== For counts of detected and suppressed errors, rerun with: -v
==1213== ERROR SUMMARY: 3 errors from 1 contexts (suppressed: 0 from 0)

有什么提示可以导致这个吗?

最佳答案

这是你的问题:

strBuffer = realloc(strBuffer, numEx);

如果您对 realloc() 的调用失败,则它会返回一个空指针,但不会释放原始内存分配。

需要先检查返回值,如果成功则赋值给原指针:

char *tmpBuffer = realloc(strBuffer, numEx);
if (!tmpBuffer) {
free(strBuffer);
puts("realloc() failed");
exit(1);
}
else {
strBuffer = tmpBuffer;
}

您的代码还有一些其他问题,包括:

  • 如果 strBuffer 为 NULL,则将其传递给 free() 没有意义。

  • sizeof() 不是运行时函数,因此它不知道分配了多少内存。

  • strBuffer = malloc(sizeof(char)*maxS+1); 有点草率。我想你的意思是 strBuffer = malloc(sizeof(char)*(maxS+1));,但你可以只输入 strBuffer = malloc(maxS+1);因为根据定义,sizeof(char) 为 1。

关于c - 尽管内存已被释放,Valgrind 仍检测到内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27238998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com