【问题标题】:Solved: Question about freeing malloc()ed memory in C已解决:关于在 C 中释放 malloc()ed 内存的问题
【发布时间】:2023-02-13 22:42:24
【问题描述】:

我正在学习 CS50 课程(所以请不要给我确切的正确答案,但请指出正确的方向!

我让我的程序(如下)开始工作(虽然我不确定我是否以“正确的方式”做到了);它从 plates.txt 打印 8 个车牌。但是,valgrind 仍然告诉我丢失了一些字节。我确信这与我在循环中分配内存的“临时”事物有关。我只是不知道如何解决它。如果有人能指出我正确的方向,那就太好了!

瓦尔格林德:

==18649== HEAP SUMMARY:
==18649== in use at exit: 49 bytes in 7 blocks
==18649== total heap usage: 10 allocs, 3 frees, 4,624 bytes allocated
==18649==
==18649== 49 bytes in 7 blocks are definitely lost in loss record 1 of 1
==18649== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==18649== by 0x109257: main (license.c:39)
==18649==
==18649== LEAK SUMMARY:
==18649== definitely lost: 49 bytes in 7 blocks
==18649== indirectly lost: 0 bytes in 0 blocks
==18649== possibly lost: 0 bytes in 0 blocks
==18649== still reachable: 0 bytes in 0 blocks
==18649== suppressed: 0 bytes in 0 blocks
==18649==
==18649== For lists of detected and suppressed errors, rerun with: -s
==18649== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

程序代码:

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

int main(int argc, char *argv[])
{
    // Check for command line args
    if (argc != 2)
    {
        printf("Usage: ./read infile\n");
        return 1;
    }

    // Create buffer to read into
    char buffer[7];

    // Create array to store plate numbers
    char *plates[8];

    // Create a pointer that will later point to a place in memory on the heap for strcpy
    char *temp = NULL;

    FILE *infile = fopen(argv[1], "r");

    if (infile == NULL)
    {
        printf("File not found.\n");
        return 1;
    }

    int idx = 0;

    while (fread(buffer, 1, 7, infile) == 7)
    {
        // Replace '\n' with '\0'
        buffer[6] = '\0';

        // Allocate memory to temporarily store buffer contents
        temp = malloc(sizeof(buffer));

        // Copy buffer contents to temp
        strcpy(temp, buffer);

        // Save plate number in array
        plates[idx] = temp;
        idx++;
    }

    fclose(infile);

    for (int i = 0; i < 8; i++)
    {
        printf("%s\n", plates[i]);
    }

    free(temp);

    return 0;
}

我关闭了文件并释放了堆中的“临时”位置。但是,我 malloc() temp 多次,但我不能 free(temp) 多次?

【问题讨论】:

  • 提示:你只释放最后一个盘子的内存。
  • 考虑一下:您在循环中调用malloc。你不应该在循环中调用free吗?
  • 鉴于显然只有 8 个盘子并且每个盘子的长度都很短,您甚至需要动态分配内存吗?
  • 不要做free(temp);。提示:而是释放每个 malloc'ed temp.... 你确实将它们保存在另一个变量中
  • OT: for (int i = 0; i &lt; 8; i++) 如果文件只包含 2 个盘子会怎样?提示:也许 idx 在这里很有用

标签: c pointers malloc free fread


【解决方案1】:

free(temp); 是错误的,它只是删除了最后分配的项目。

由于您在循环中调用了malloc,因此您还必须在循环中调用free。经验法则是每个malloccall 都必须与freecall 匹配。

所以你必须创建一个for循环遍历char *plates[8];free每个plates指针指向的所有内容。

【讨论】:

  • 是的!成功了,谢谢!
【解决方案2】:

您需要释放所有分配的指针。

for(i = 0; i < idx; i++) 
   free(plates[i]);

您也可以很容易地超出数组范围,因为您不检查索引

 while (idx < 8 && fread(buffer, 1, 7, infile) == 7)

打印也是错误的,因为您假设您已经阅读了所有 8 个块。

    for (int i = 0; i < idx; i++)
    {
        printf("%s
", plates[i]);
    }


【讨论】:

  • 谢谢,这有效!
猜你喜欢
  • 1970-01-01
  • 2015-09-10
  • 2010-11-16
  • 1970-01-01
  • 2015-08-12
  • 1970-01-01
  • 1970-01-01
  • 2021-04-28
相关资源
最近更新 更多