c - 我的代码中是否存在内存泄漏? (使用指针存储字符串)

标签 c string pointers memory-leaks

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

int main(void) {
    int x;
    int *in, *begin;
    in = (int *)malloc(sizeof(int));
    begin = in;
    while ((x = getchar()) != EOF) {
        *in = x;
        in++;
        in = (int *)malloc(sizeof(int));
    }
    *in = EOF;
    while ((x = *begin) != EOF) {
        putchar(x);
        begin++;
    }
    free(in);
    return 0;
}

我暗暗怀疑它确实如此。

在这个程序中,我尝试使用指针将不确定大小的用户输入存储到内存中,而不是使用 char string[255]; fgets(string, sizeof(string));

编辑:当我运行程序时,程序没有崩溃或发生任何事情,我只是觉得有内存被分配但没有被释放。

最佳答案

是的,程序有内存泄漏。

int *in, *begin;
in = (int *)malloc(sizeof(int));  /* allocate space for 1 int, at location "X" */
begin = in;
while ((x = getchar()) != EOF) {
    *in = x; 
    in++;    /* "in" increments address (to location) "X+1" */
    in = (int *)malloc(sizeof(int)); /* address "X+1" is lost as malloc returns  
                                        a different memory location, *not*
                                        necessarily at "X+2". Access to 
                                        previous data other than pointed to by 
                                        "begin" is lost */
}

*in = '\0';  /* this makes probably more senese than assigining EOF here */

分配内存时需要相应调用free()

另外,我认为输入没有正确存储。

in 从不 给定一个连续 内存块来存储数据。相反,存储 int 大小的单个内存位置被重复分配并分配给 in,但我们真的不知道这个内存在哪里,所以所有这些分配都丢失了,因为只有一个指针 in 正在跟踪它们。

换句话说,泄漏包括为 int 的大小重复分配内存,将其分配给 in,然后在下一次丢失对该位置的任何引用通过循环。

变量 begin 最初指向输入的第一个项目,但随后随着其指针值在输出循环中重复递增 1 而陷入未知内存。

更好的方法是在开始时分配一个更大的连续 缓冲区,然后在递增in 指针时使用它,或者从一个较小的数量,但随后监视内存使用和 realloc() 根据需要更多(但更多的开销以节省一些内存)。

此外,在第一个循环结束时,与其将 EOF 分配给 in,不如放入空字符更有意义。

最后,程序底部的 free(in) 调用仅释放一个内存位置,不会释放其他先前分配的内存。

这是一个快速组合的版本,我尝试对原始代码进行最小的更改保持您的代码结构完整(我相信您有首先用两个循环以这种方式编写它的原因)尽管这可以只用一个循环编写得更紧凑。

请注意,我最初为 100 个字符分配了空间,可根据您的需要进行调整,或者最初分配较少的空间,但随后会跟踪内存消耗并根据需要 realloc() 更多内存(我认为这是您的初衷,但没有完全正确实现)。

int main(void) {
    int x;
    int *in, *begin;
    int *start_loc;
    in = (int *)malloc(sizeof(int) * 100); /* continious space */
    begin = in;
    start_loc = in; /* keep track of start location for final free() call */

    while ((x = getchar()) != EOF) {
        *in = x;
        in++;
    }
    *in = 0;  /* terminator for the input string/data */

    while (*begin != 0) {   /* simplified */
        putchar(*begin);
        begin++;
    }

    free(start_loc);  /* free allocated memory */
    return 0;
}

这可以在不使用新变量 start_loc 的情况下编写(例如通过重用 in),但我选择这样写是为了强调保持跟踪内存分配的开始以及正确释放分配的内存的能力,从而解决内存泄漏问题。

关于c - 我的代码中是否存在内存泄漏? (使用指针存储字符串),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11068037/

相关文章:

c++ - CUDA 将继承的类对象复制到设备

c++ - 使用 Eclipse CDT 进行 Pintool 开发

c - 尝试在 malloc (c) 中使用

c - 使用函数指针进行冒泡排序

php - 限制字符串长度

c++ - 带有指针数据的 OpenGL glBufferData

c - 在c中接收udp文本文件

php - 如何识别数据库列中的换行符

c - 低级 IO read() 和 write()

char **s 与 char *s[],何时以及如何使用它们?