简体   繁体   English

free()将在指向C中数组的第二个指针上工作吗?

[英]Will free() work on a second pointer to an array in C?

Let's say I have some code set up like this: 假设我设置了一些这样的代码:

#include <stdlib.h>
#include <stdio.h>

int main() {
    char* primary = malloc(10);    // main pointer to heap memory
    char* secondary = primary;     // an alias for the main pointer
    free(secondary);
}

Will free(secondary) also release memory that was assigned to primary ? free(secondary)也会释放分配给primary内存吗?

Yes, free() will work on any pointer that holds an address that in turn was returned by any of malloc() , calloc() or realloc() . 是的, free()可以在任何持有地址的指针上工作,该地址又由malloc()calloc()realloc()的任何一个返回。 Although doing that is a little bit dangerous since you risk free() ing the pointer twice. 尽管这样做有点危险,因为您有两次free()指针的风险。 Only one of the two shall be passed to free() and after you do you cannot do it again with either of them. 只能将两者之一传递给free() ,执行之后,您将无法再使用它们之一进行传递。

It's a common practice to set the pointer to NULL right after passing it to free() to avoid having a dangling poitner and thus avoid freeing a pointer more than once " accidentally ", in the scenario you describe you risk setting only one of the pointers to NULL . 通常的做法是在将指针传递给free()之后立即将其设置为NULL以避免有悬挂的Poitner ,从而避免多次“ 意外 ”释放指针,在这种情况下,您可能只设置其中一个指针为NULL

In short, if you do that primary will become another dangling pointer which is as twice as dangerous as having just secondary as the dangling pointer. 总之,如果你这样做, primary将成为又一个悬摆指针是作为两倍具有只是危险的secondary为悬摆指针。

The pointer values are the same. 指针值是相同的。 When you assign primary to secondary , the two pointers point to the same address of memory allocated by malloc() . 当您将primary分配给secondary ,这两个指针指向malloc()分配的同一内存地址。 You may free either one of them (but not both). 您可以free其中任何一个(但不能同时free两个)。

This is particularly useful in cases where you don't actually call malloc() or free() yourself. 这在您自己实际不调用malloc()free()情况下特别有用。

Consider the POSIX function strdup() , which copies a string to newly allocated memory. 考虑POSIX函数strdup() ,该函数将字符串复制到新分配的内存中。 Essentially calling malloc() (or a similar function) for you. 本质上是为您调用malloc() (或类似的函数)。

char[] strarr = "I am a string.";
char* mystr = strdup(strarr);

/* do some stuff */

free(mystr)

strdup() likely stored the result of its memory allocation function in a variable, and mystr was almost certainly not its name within the body of that function. strdup()可能将其内存分配函数的结果存储在一个变量中,而mystr几乎可以肯定不是其在函数体内的名称。 That variable was returned and reassigned to mystr , which you then have to free . 该变量已返回并重新分配给mystr ,然后必须free

Then how come we cannot use sizeof or some other built-in function to find the size of a pointer array? 那么,为什么我们不能使用sizeof或其他内置函数来找到指针数组的大小呢?

Do not confuse language with library. 不要将语言与库混淆。 sizeof is not a function, and malloc is not built-in. sizeof不是函数,并且malloc不是内置的。

In C, sizeof is an operator , not a function. 在C中, sizeof运算符 ,而不是函数。 (Note that you don't need to declare it.) You can say things like: (请注意,您无需声明它。)您可以这样说:

size_t size = sizeof(void*);

because you're not passing a variable to sizeof , but an expression. 因为您没有将一个变量传递给sizeof ,而是一个表达式。 The expression has a type, and every type has a size. 表达式有一个类型,每个类型都有一个大小。

When you say 当你说

char greeting[] = "hello";
size_t len = sizeof greeting;

len is 6 because greeting has the type char[6] . len是6,因为greeting的类型为char[6] Because sizeof is an operator, we can dispense with the parentheses. 因为sizeof是运算符,所以我们可以省去括号。 Parentheses are usually used with it, but only to avoid operator-precedence issues. 通常将圆括号与之配合使用,但这仅是为了避免出现运算符优先级问题。

The C standard library defines malloc and free , but no (shall we call it) size_of function to return the size of the allocated block. C标准库定义了mallocfree ,但是没有(我们称它为) size_of函数来返回分配的块的大小。 An implementation could provide such a function. 一个实现可以提供这样的功能。 Compared to maintaining the heap, it's technically trivial. 与维护堆相比,从技术上讲它是微不足道的。

Why is " size_of " not commonly provided? 为什么通常不提供“ size_of ”? I would say, because it's not much needed. 我会说,因为它不需要太多。 While functions like memset may operate on whole blocks of memory, they're useful for partial blocks, too. 尽管诸如memset功能可以在整个内存块上运行,但它们对于部分内存块也很有用。 The number of bytes in a block is frequently less interesting than the number of higher-level elements it contains ( struct or even just int ). 块中的字节数通常不如其包含的更高级别元素( struct甚至是int )有趣。 We may note that the C++ STL algorithms, designed a decade later, also do not operate on whole collections, but take start & stop arguments. 我们可能会注意到,十年后设计的C ++ STL算法也不能在整个集合上运行,而是采用start和stop参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM