我的(自定义)程序如何泄漏内存?我正在为 pset5 做准备
How is my (custom) program leaking memory? I am preparing myself for pset5
我正在尝试了解内存分配和指针的工作原理,因为我发现 CS50 (pset5) 的问题集太多了。
我做了一个简单的程序,从数组中读取字符,然后将它们写入新的文本文件和终端。
程序运行正常,但它正在泄漏内存。
特别是对于在字符串中遇到的每个 \n,valgrind 声明它在另外 1 个块中丢失内存。对于(char *c 的)字符串中的每个字符,它表示又泄漏了 1 个字节。
我做错了什么?
终端的图像link:https://i.stack.imgur.com/ANtAs.png
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (void)
{
FILE *fp;
char *c = "One\nTwo\n";
// Open file for writing (reading and writing works too, we can use 'w+' for that).
fp = fopen("file.txt", "w");
// Write data to the file.
fwrite(c, strlen(c), 1, fp);
// Seek to the beginning of the file
fseek(fp, 0, SEEK_SET);
// close file of the file pointer (the text file).
fclose(fp);
// initialize a counter for the amount of characters in the current word that is being read out of the file.
int char_count = 0;
// initialize an address for the first character in a string.
char *buffer_temp_word = NULL;
// Read and display data, using iterations over each character.
// Open the file in read mode.
fp = fopen("file.txt", "r");
// initiate a for loop.
// condition 1: getting a character from the fp stream does not equal reaching the end of the file
// condition 2: the amount of iterations is not above 60 (failsafe against endless loops).
for (int i = 0; fgetc(fp) != EOF && i <= 60 ; i++)
{
//add a counter to the amount of characters currently read.
char_count++;
// seek the pointer 1 place back (the 'IF' function moves the pointer forward 1 place forward for each character).
fseek(fp , -1L, SEEK_CUR);
// get the character value of the current spot that the pointer of the read file points to.
char x = fgetc(fp);
buffer_temp_word = realloc(buffer_temp_word, (sizeof(char)) * char_count);
//the string stores the character on the correct place
//(the first character starts at memory location 0, hence the amount of characters -1)
buffer_temp_word[char_count - 1] = x;
// check for the end of the line (which is the end of the word).
if(x == '\n')
{
//printf("(end of line reached)");
printf("\nusing memory:");
// iterate trough characters in the memory using the pointer + while loop, option 2.
while(*buffer_temp_word != '\n')
{
printf("%c", *buffer_temp_word);
buffer_temp_word++;
}
printf("\nword printed succesfully");
// reset the pointer to the beginning of the buffer_temp_word string (which is an array actually).
buffer_temp_word = NULL;
free(buffer_temp_word);
// reset the amount of characters (for the next word that will be read).
char_count = 0;
}
printf("%c", x);
}
fclose(fp);
free(buffer_temp_word);
return(0);
}
您在释放之前将 buffer_temp_word
设置为 NULL:
// reset the pointer to the beginning of the buffer_temp_word string (which is an array actually).
buffer_temp_word = NULL;
free(buffer_temp_word);
如果您使用 clang 的静态分析器,它可以引导您通过代码中的路径来显示您的内存泄漏。
此外,将指针设置为 NULL 不会 将其重置为它指向的数组的起始位置,而是将其设置为 NULL。考虑使用 for 循环而不是 while 循环并使用计数器来索引数组:
for(int j = 0; buffer_temp_word[j] != '\n'; ++j)
{
printf("%c", buffer_temp_word[j]);
}
然后不要将 buffer_temp_word
设置为 NULL,也不要在此循环后立即 free
它。该程序已设置为 realloc
或稍后 free
。
我正在尝试了解内存分配和指针的工作原理,因为我发现 CS50 (pset5) 的问题集太多了。
我做了一个简单的程序,从数组中读取字符,然后将它们写入新的文本文件和终端。
程序运行正常,但它正在泄漏内存。 特别是对于在字符串中遇到的每个 \n,valgrind 声明它在另外 1 个块中丢失内存。对于(char *c 的)字符串中的每个字符,它表示又泄漏了 1 个字节。
我做错了什么?
终端的图像link:https://i.stack.imgur.com/ANtAs.png
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (void)
{
FILE *fp;
char *c = "One\nTwo\n";
// Open file for writing (reading and writing works too, we can use 'w+' for that).
fp = fopen("file.txt", "w");
// Write data to the file.
fwrite(c, strlen(c), 1, fp);
// Seek to the beginning of the file
fseek(fp, 0, SEEK_SET);
// close file of the file pointer (the text file).
fclose(fp);
// initialize a counter for the amount of characters in the current word that is being read out of the file.
int char_count = 0;
// initialize an address for the first character in a string.
char *buffer_temp_word = NULL;
// Read and display data, using iterations over each character.
// Open the file in read mode.
fp = fopen("file.txt", "r");
// initiate a for loop.
// condition 1: getting a character from the fp stream does not equal reaching the end of the file
// condition 2: the amount of iterations is not above 60 (failsafe against endless loops).
for (int i = 0; fgetc(fp) != EOF && i <= 60 ; i++)
{
//add a counter to the amount of characters currently read.
char_count++;
// seek the pointer 1 place back (the 'IF' function moves the pointer forward 1 place forward for each character).
fseek(fp , -1L, SEEK_CUR);
// get the character value of the current spot that the pointer of the read file points to.
char x = fgetc(fp);
buffer_temp_word = realloc(buffer_temp_word, (sizeof(char)) * char_count);
//the string stores the character on the correct place
//(the first character starts at memory location 0, hence the amount of characters -1)
buffer_temp_word[char_count - 1] = x;
// check for the end of the line (which is the end of the word).
if(x == '\n')
{
//printf("(end of line reached)");
printf("\nusing memory:");
// iterate trough characters in the memory using the pointer + while loop, option 2.
while(*buffer_temp_word != '\n')
{
printf("%c", *buffer_temp_word);
buffer_temp_word++;
}
printf("\nword printed succesfully");
// reset the pointer to the beginning of the buffer_temp_word string (which is an array actually).
buffer_temp_word = NULL;
free(buffer_temp_word);
// reset the amount of characters (for the next word that will be read).
char_count = 0;
}
printf("%c", x);
}
fclose(fp);
free(buffer_temp_word);
return(0);
}
您在释放之前将 buffer_temp_word
设置为 NULL:
// reset the pointer to the beginning of the buffer_temp_word string (which is an array actually).
buffer_temp_word = NULL;
free(buffer_temp_word);
如果您使用 clang 的静态分析器,它可以引导您通过代码中的路径来显示您的内存泄漏。
此外,将指针设置为 NULL 不会 将其重置为它指向的数组的起始位置,而是将其设置为 NULL。考虑使用 for 循环而不是 while 循环并使用计数器来索引数组:
for(int j = 0; buffer_temp_word[j] != '\n'; ++j)
{
printf("%c", buffer_temp_word[j]);
}
然后不要将 buffer_temp_word
设置为 NULL,也不要在此循环后立即 free
它。该程序已设置为 realloc
或稍后 free
。