【发布时间】:2021-12-23 14:10:07
【问题描述】:
20 多年前,我对用 C 编写一些小程序有所了解,但即使在那个时候,我也可能并不是一直都在做正确的事情。现在我又想学C了,所以我真的是个新手。
根据这篇文章: Using realloc to shrink the allocated memory ,我做了这个测试,效果很好,但是让我很困扰:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int test (char *param) {
char *s = malloc(strlen(param));
strcpy(s, param);
printf("original string : [%4d] %s \n", strlen(s), s);
// reduce size
char *tmp = realloc(s, 5);
if (tmp == NULL) {
printf("Failed\n");
free(s);
exit(1);
} else {
tmp[4] = 0;
}
s = tmp;
printf("the reduced string : [%4d] %s\n", strlen(s), s );
free(s);
}
void main(void){
test("This is a string with a certain length!");
}
- 如果我遗漏了“tmp[4] = 0”,那么我仍然会取回整个字符串。这是否意味着字符串的其余部分仍在内存中,但不再分配?
- c 如何释放内存?它是自行跟踪内存还是由操作系统处理?
- 我释放了 s 字符串“free(s)”,是否还需要释放 tmp str(它确实指向同一个内存块,但它持有的(相同)地址可能存储在另一个内存位置?
这些很可能只是基础知识,但到目前为止我所阅读的内容都没有给我一个明确的答案(包括提到的文章)。
【问题讨论】:
-
char *s = malloc(strlen(param));太短1-- 回忆一下'\0'(nul 终止字符) -
realloc()自动释放原始内存并返回指向重新分配内存的指针(除非新分配失败)。你不需要同时释放它们。 -
"c 怎么释放内存" -- 它依赖于实现,你不必担心。
-
一些笔记。 1)
main必须返回一个int。 2)test永远不会返回任何东西,它应该是void test。 3)strlen返回一个size_t。使用特殊的%zu格式,而不是%d。 4)malloc+strcpy有分配错误内存量的风险;你差了一个。请改用strdup。 5) 打开编译器警告。 -
指针只是一个普通变量,它保存一个地址作为它的值。当您
free()内存时,您正在传递内存块的起始地址。当您执行s = tmp;时,s和tmp都拥有与其值相同的地址(例如,它们都指向内存中的相同地址)。你只需要释放一次(否则你会发现"double-free or corruption"错误盯着你......)还要注意strdup()是POSIX 不是标准C,所以你可能有也可能没有它。
标签: c