提问人:gotter 提问时间:2/27/2023 最后编辑:gotter 更新时间:2/27/2023 访问量:108
这是在 c 中释放内存的可接受方法吗?
Is this an acceptable way to deallocate memory in c?
问:
我有一个函数,它读取文件并为文件内容分配内存,并将文件内容分配给指针,然后返回指针。然后,我使用循环遍历字符串并使用指针算术打印每个字符。
我很确定我可以/应该使用 realloc 在每次迭代中重新分配更少的内存,而不是使用计数器跟踪迭代,但我不确定如何实现它。
因此,在代码末尾,当我调用时,我从指针变量中减去计数器,以解除分配指针最初指向的地址。free()
contents
以下是我用来读取文件的代码以及我的循环所在的主函数:
char *read_file(const char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
perror("Failed to open file");
exit(EXIT_FAILURE);
}
// Obtain information about the file
struct stat st;
if (fstat(fileno(fp), &st) != 0) {
perror("Failed to get file information");
exit(EXIT_FAILURE);
}
size_t file_size = st.st_size;
// Allocate a buffer to hold the contents of the file
char *buffer = (char *) malloc(file_size + 1);
if (buffer == NULL) {
perror("Failed to allocate memory");
exit(EXIT_FAILURE);
}
// Read the contents of the file into the buffer
size_t bytes_read = fread(buffer, 1, file_size, fp);
buffer[bytes_read] = '\0';
// Close the file and return the buffer
fclose(fp);
return buffer;
}
int main() {
char *contents = read_file("testNote.txt");
int counter = 0;
while (*contents != '\0') {
printf("%c", *contents);
++counter;
++contents;
}
free(contents - counter);
return 0;
}
据我在实验后所知,这是按照我所认为的方式工作的,但我只是想确保我在这里没有做任何有害的事情
答:
6赞
dbush
2/27/2023
#1
你正在做的事情会奏效。每次递增时,也会递增,因此为您提供可以释放的原始指针。contents
counter
contents - counter
当然,更好的方法是使用临时指针在分配的内存中递增,以便您可以使用原始 to .free
int main() {
char *contents = read_file("testNote.txt");
char *tmp = contents;
while (*tmp != '\0') {
printf("%c", *tmp);
++tmp;
}
free(contents);
return 0;
}
评论
0赞
tstanisl
2/27/2023
最好使用 loop:for
for (char *tmp = contents; *tmp != '\0'; ++tmp) { ... }
1赞
Nick ODell
2/27/2023
#2
不,这不安全。
假设您读取的文件大于 2147483647 字节或大约 2 GB。然后,当您到达文件末尾时,overflow 的值为负数。当你减去 时,你得到的地址与你得到的地址不同。最好的情况是它崩溃。最坏的情况是它会损坏堆并继续运行。counter
contents - counter
malloc()
我建议使用@dbush的建议。即使您可以保证不会获得 2GB 的文件,它们的代码仍然更容易推理。
评论
size_t
int
main()
malloc()
int
对于大文件,可能会溢出。