是的,程序有内存泄漏。
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
从来没有给一个连续的内存块来存储数据。取而代之的是,一个存储 an 大小的内存位置int
被重复分配并分配给in
,但我们并不真正知道该内存在哪里,因此所有这些分配都丢失了,因为只有一个指针in
在跟踪它们。
换句话说,泄漏包括重复为 a 的大小分配内存int
,将其分配给in
,然后在下一次循环中丢失对该位置的任何引用。
变量begin
最初指向输入的第一个项目,但随后由于其指针值在输出循环中重复递增 1 而陷入未知内存。
更好的方法是在开始时分配一个更大的连续缓冲区,然后在增加指针时使用它in
,或者从较小的数量开始,然后realloc()
根据需要监视内存使用和更多(但要节省更多开销几句记忆)。
此外,在第一个循环结束时,而不是分配EOF
to 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
),但我选择这样编写它是为了强调跟踪内存分配开始的重要性以及正确释放分配的内存的能力,因此解决您的内存泄漏问题。