hazrmard
hazrmard

Reputation: 3661

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?

Upvotes: 0

Views: 127

Answers (3)

James K. Lowden
James K. Lowden

Reputation: 7837

Then how come we cannot use sizeof or some other built-in function to find the size of a pointer array?

Do not confuse language with library. sizeof is not a function, and malloc is not built-in.

In C, sizeof is an operator, not a function. (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. 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]. Because sizeof is an operator, we can dispense with the parentheses. 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. An implementation could provide such a function. Compared to maintaining the heap, it's technically trivial.

Why is "size_of" not commonly provided? 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. 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). We may note that the C++ STL algorithms, designed a decade later, also do not operate on whole collections, but take start & stop arguments.

Upvotes: 1

PC Luddite
PC Luddite

Reputation: 6088

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(). You may free either one of them (but not both).

This is particularly useful in cases where you don't actually call malloc() or free() yourself.

Consider the POSIX functionstrdup(), which copies a string to newly allocated memory. Essentially calling malloc() (or a similar function) for you.

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. That variable was returned and reassigned to mystr, which you then have to free.

Upvotes: 2

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53006

Yes, free() will work on any pointer that holds an address that in turn was returned by any of malloc(), calloc() or realloc(). Although doing that is a little bit dangerous since you risk free()ing the pointer twice. Only one of the two shall be passed to free() and after you do you cannot do it again with either of them.

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.

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.

Upvotes: 4

Related Questions