假设我有以下代码:
int *ptr = (int*) malloc(0), *ptr2;
ptr2 = (int*) malloc(4 * sizeof(int));
*(ptr2 + 1) = 3;
ptr = ptr2;
free(ptr)
Run Code Online (Sandbox Code Playgroud)
调用 free(ptr) 是否对 ptr 指向的新内存块或空指针有效?
是的,在您的示例中ptr设置为ptr2which 来自malloc。
所以,free(ptr); 是有效的(例如,就像我们所做的那样free(ptr2);)。
但是,现在,我们已经丢失了原始值,因此第一个ptr块现在是内存泄漏。也就是说,没有变量具有原始值,因此它永远无法被释放。 malloc
要解决这个问题,但保留原始代码,我们可以这样做:
\nint *ptr = (int *) malloc(0), *ptr2;\n\nptr2 = (int *) malloc(4 * sizeof(int));\n*(ptr2 + 1) = 3;\n\n// to prevent a leak of the first malloc ...\nint *ptr3 = ptr;\n\n// without ptr3, this would "leak" the original value of ptr\nptr = ptr2;\nfree(ptr)\n\n// free the first block ...\nfree(ptr3);\nRun Code Online (Sandbox Code Playgroud)\n旁注: malloc returns void *,适用于任何指针类型,因此无需转换返回值。请参阅:我是否投射 malloc 的结果?
因此,在代码中执行以下操作(例如):
\nptr2 = malloc(4 * sizeof(int));\nRun Code Online (Sandbox Code Playgroud)\n仍然存在一些额外的代码复制。sizeof(int)如果我们改变了 的类型,就必须改变ptr2。
因此,为了让代码“面向未来”,许多人更喜欢:
\nptr2 = malloc(sizeof(*ptr2) * 4);\nRun Code Online (Sandbox Code Playgroud)\n更新:
\n\n\n\n
malloc(0)您还可以添加有关实现定义行为的注释。\xe2\x80\x93\nchqrlie
是的,malloc(0)具有实现定义的行为。一些可能性:
NULL。IMO,最好的选择malloc(1)由于这些原因我会避免使用malloc(0)。它是“脆弱的”并且具有边际效用。
我[大多数]看到它被新手程序员使用,他们计划realloc在循环中使用并相信他们不能调用realloc指针NULL。
不过,realloc接受NULL指针就好了。
例如,如果我们要将一个充满整数的文件读入数组,并且我们不知道文件中有多少个数字,我们可能会这样做:
\n#include <stdio.h>\n#include <stdlib.h>\n\nint\nmain(int argc,char **argv)\n{\n\n if (argc < 2)\n exit(3);\n\n// NOTE: novices do this ...\n#if 0\n int *ptr = malloc(0);\n// NOTE: experienced programmers do this ...\n#else\n int *ptr = NULL;\n#endif\n\n // number of elements in the array\n size_t count = 0;\n\n // open the input file\n FILE *input = fopen(argv[1],"r");\n if (input == NULL) {\n perror(argv[1]);\n exit(4);\n }\n\n while (1) {\n // increase array size\n ptr = realloc(ptr,sizeof(*ptr) * (count + 1));\n\n // out of memory ...\n if (ptr == NULL) {\n perror("realloc");\n exit(5);\n }\n\n // decode one number from file\n if (fscanf(input,"%d",&ptr[count]) != 1)\n break;\n\n // advance the count\n ++count;\n }\n\n // close the input stream\n fclose(input);\n\n // trim array to actual size used\n ptr = realloc(ptr,sizeof(*ptr) * count);\n\n // print the array\n for (size_t idx = 0; idx < count; ++idx)\n printf("%zu: %d\\n",idx,ptr[idx]);\n\n // free the array\n free(ptr);\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n注意:在极少数特殊情况下,这样做malloc(0) 确实有意义。通常,指针必须传递给一些代码来区分NULL分配malloc(0)与常规分配。但是,它们是高级用法,我不会向初学者推荐它们。