1

From what I know, malloc and calloc are just book keeping APIs on underlying memory. Keeping this in mind, I wonder if a call to free() will free up an entire array whose individual elements have been allocated memory through independent calls to malloc (or calloc).

Precisely, I have the following code:

int *num,* num_start;

num_start=num;

for(i=0;i<N;i++)
{
    num = (int *)calloc(0, sizeof(int));
    num++;
}

free(num_start);

Will free(num_start) free up the entire array of N integer elements which have been dynamically allocated space, independently?

Pinak
  • 11
  • 2
  • 1
    Nothing about this changed in C++11, so that tag's redundant. In fact C++ is entirely irrelevant unless you're talking about C++-specific behaviour for this C code, of which I can't see any. – tadman Aug 16 '20 at 09:52
  • 2
    Note: `num_start` is not a pointer despite what you might think. You're also asking for a zero length allocation, which seems wrong. – tadman Aug 16 '20 at 09:53
  • 3
    Note: num_start is assigned before num has been assigned any meaningful value. – Finn Aug 16 '20 at 09:55
  • 2
    You need to pair each `malloc()` with a corresponding `free()`. So in your code you have `N` mallocs (in a loop), you need `N` frees (in a loop) – pmg Aug 16 '20 at 09:57
  • Can you get this code to compile without warnings? Does it crash or not when you run it? How about with asan? – Paul Hankin Aug 16 '20 at 10:18

2 Answers2

1

The "code" you posted does not make any sense and is wrong.

int *num, num_start;
num_start=num;

num_start is an integer not pointer.

for(i=0;i<N;i++)
{
    num = (int *)calloc(0, sizeof(int));
    num++;
}

to be honest I do not understand what what this code is supposed to do, but for sure is wrong

if you want to allocate memory for N integers

int *num = calloc(N, sizeof(*num));

and to free you only need

free(num);

Or if you want to allocate pointer to store N pointers to N integers

int **allocate(size_t N)
{
    int **num = malloc(N * sizeof(*num));
    for(size_t i=0; i<N; i++)
    {
        num[i] = calloc(N, sizeof(**num));
    }
    return num;
}

void arrayfree(int **num, size_t size)
{
    for(size_t i = 0; i < size; i++)
    {
        free(num[i]);
    }
    free(num);
}

When you allocate memory you have to check if the operation was successful. Those checks are not included in the example to make the code easier to read.

0___________
  • 60,014
  • 4
  • 34
  • 74
0

The calloc() and malloc() functions return a pointer to the allocation which doubles as a handle to release that memory. While you're free to make copies of that pointer and manipulate those as you see fit, when you call to free() you must provide the original value.

That is to say this does work:

// Original allocation
int* x = calloc(42, sizeof(int));

// Making a new (independent) copy of the pointer to a new pointer
int* p = x;

// Arbitrary pointer manipulation and mangling
x++;

// Freeing with the copied value
free(p);

You can also get a bit adventurous, so long as you return to your original destination:

int* x = calloc(42, sizeof(int));

x += 40;
x -= 30;
x += 10;
x -= 13;
x -= 7;

free(x);

Where here x has returned to its original value after a short journey. In general practice it's better to preserve the original pointer than to have to reconstruct it later. Make copies if you're intending to manipulate them.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • 1
    use objects in `sizeof` not types – 0___________ Aug 16 '20 at 10:12
  • @P__J__ That's an alternate approach that I've seen becoming more popular, but this is the more traditional approach. Like spaces vs. tabs [the debate is lively](https://softwareengineering.stackexchange.com/questions/201104/sizeof-style-sizeoftype-or-sizeof-variable). – tadman Aug 16 '20 at 10:13
  • It was "traditional" approach for years. It was simple not taught by the teachers as they were thinking that int *x = malloc(sizeof(*x)); dereferences the pointer :). – 0___________ Aug 16 '20 at 10:17
  • @P__J__ In the K&R C book, which I leaned from back in the day, they use both forms and switch to whatever makes the most sense in any given situation. Sometimes it's the type, sometimes it's the variable or "object". – tadman Aug 16 '20 at 10:19
  • `K&R C book` rather obsolete – 0___________ Aug 16 '20 at 10:20
  • @P__J__ It wasn't when I was using it, the Second Edition was still brand new, and I'm not the only one who's learned that way. – tadman Aug 16 '20 at 10:20
  • Abstracting from the book programming standards evolve. After zillions of hard to spot errors caused by `sizeof(type)` it is good to show novice programmers the more (errorwise) correct way. – 0___________ Aug 16 '20 at 10:23
  • 2
    @tadman: One question with no answers less than six years old and a top pro-object answer with an order of magnitude more votes up than the leading pro-size answer (with one intervening pro-intent answer) is not “lively” debate. – Eric Postpischil Aug 16 '20 at 10:42
  • 2
    @tadman: I learned C from the first edition, but that does mean I stopped there. – Eric Postpischil Aug 16 '20 at 10:43