Is malloc dynamic memory allocation?
Asked Answered
M

4

5

I was told by an instructor that p = (int*)malloc(5 * sizeof(int)) is NOT dynamic memory allocation and that p=(int*)malloc(n * sizeof(int)) is dynamic memory allocation.

The instructor was talking about basic data structures and was teaching arrays. He had told us the traditional way to create arrays using the int arr[100] syntax, but then he introduced us with malloc.

According to him as the memory size doesn't change it's not dynamic I guess.

From what I could gather from the internet, malloc assigns memory at runtime, and when memory is assigned at runtime its dynamic memory allocation. So I think both the malloc statements are dynamic memory allocations. Is there something wrong with my reasoning?

Mcmillan answered 3/8, 2020 at 12:12 Comment(8)
I think both the malloc statements are dynamic memory allocations and you are right. Is there something wrong with my reasoning? No.Endospore
We can't really tell you what the instructor actually meant without the full context of what was said. But clearly malloc is dynamic allocation and it even says it in the manual page: malloc, free, calloc, realloc - allocate and free dynamic memoryJusten
Casting the result value from malloc() is, at best, redundant and may hide an error the compiler would catch in the absence of the cast.Thinnish
In C language, yes both are what's called dynamic memory allocation. In normal language, however, I can understand the point of your instructor: a hardcoded 5 is less "dynamic", as you can't change it at runtime. Of course this reasoning is very dependent on the needs of your program. However, from a technical point of view, you are correct and the instructor is not.Houle
@Justen The instructor was talking about basic data structures and was teaching arrays. He had told us the traditional way to create arrays using the int arr[100] syntax, but then he introduced us with malloc. Then he told the first line as you see in the question.Mcmillan
May be what your instructor had in mind was that if you know in advance that you only need 5 integers then dynamic memory allocation is not necessary; int p[5] could be convenient for the problem... (but technically the first call is still dynamic allocation here).Hygrograph
I have edited my question to add some context.Mcmillan
Aside: code as p= malloc(sizeof *p * n); (no cast, no type). Easier to code right, review and maintain.Prosecute
E
8

Usually, we do refer to calls to malloc as dynamic allocation, irregardless if you're using a variable or constant. Even the man page for malloc calls it like that:

malloc, free, calloc, realloc - allocate and free dynamic memory

So for your instructors claim:

The instructor was talking about basic data structures and was teaching arrays. He had told us the traditional way to create arrays using the int arr[100] syntax, but then he introduced us with malloc.

According to him as the memory size doesn't change it's not dynamic I guess.

Well, in some sense he has a point if you look strictly at what "dynamic" means in a more general way. Right now we have a convention that calls all malloc dynamic allocation. This convention could have been the way your teacher claims without any problems. But it is not.

Furthermore, according to your teachers reasoning, using VLA:s (variable length array) or alloca with a variable would be considered dynamic allocation, but it is not. A VLA can be declared like this: int arr[n], or it's alloca equivalent: int *arr = alloca(n*sizeof(*arr)).

So even if you could argue that your teacher has a point, it would only cause confusion since it goes against the convention.

Also, the most dynamic thing about using malloc is that the allocation can be resized later. You cannot do that with arrays, not even VLA:s. And you cannot do it to memory you have allocated with alloca.

But as a sidenote, I do question your teachers competence if they teach you to write

p = (int*)malloc(n * sizeof(int)) 

instead of

p = malloc(n * sizeof(*p))
  1. The cast is not necessary and just adds clutter
  2. Using sizeof(*p) instead of sizeof(int) is safer

Related: Do I cast the result of malloc?

Excursus answered 3/8, 2020 at 12:22 Comment(5)
So in a normal English sense, he was right to not call it as dynamic, but technically both are dynamic allocations as others have pointed out in the comments.Mcmillan
@c-anirudh Yes.Excursus
That said, if the compiler sees a malloc() call with a compile time constant, and is able to prove that it sees all the uses of the result, it is allowed to optimize away the malloc() call. This is certainly a corner case, but other standard functions are routinely replaced by the compiler under similar circumstances (the canonical example is memcpy()).Hartung
@cmaster-reinstatemonica The compiler has no way of knowing whether you will link with the standard library or a user-provided malloc/free.Leaseback
@Leaseback The compiler also has no way of knowing whether you will link with the standard library or a user-provided memcpy(). Yet they routinely replace small, compile time constant memcpy() calls with inline code because that's an important optimization. What allows them to do this is the fact, that the presence and behavior of memcpy(), malloc() and free() is prescribed by the C standard itself, not some kind of auxiliary standard like POSIX.Hartung
R
5

The C standard does not define the term "dynamic memory allocation". So we can't take the C standard and lookup what dynamic memory allocation is.

The C standard talks about "Memory management functions" (i.e. aligned_alloc, calloc, malloc, realloc and free). When these functions are used it's commonly called dynamic memory allocation but - just to repeat - it's not a term from the standard.

The standard talks about "life time of objects". An objected created using one of the above memory management function is said to have "allocated storage duration" (which means that it exists until your code frees it).

Both code lines in the question makes p point to an object that has "allocated storage duration".

My guess is that you have misunderstood your teacher, i.e. misunderstood what was meant by "dynamic". Perhaps your teacher talked about the size of the allocated object, i.e.:

p = (int*)malloc(5 * sizeof(int));   // Here the size is static - always 5 ints

p = (int*)malloc(n * sizeof(int));   // Here the size is dynamic (aka depends on n)

Note: The cast, i.e. (int*), is not needed in C.

Ratoon answered 3/8, 2020 at 13:32 Comment(2)
I am pretty sure he wasn't talking about whether the size was dynamic, he was talking about the way memory was assigned. But still, I can be wrong. Thanks for the answer!Mcmillan
@c-anirudh well.. ok... I know that teachers don't always get every detail correct (nor does high rep stackoverflow user :-) but I find it hard to believe that your teacher made such a fundemental mistake as described in your question. But then again - I don't know your teacher ;-)Ratoon
S
4

Either you’re misunderstanding the point your instructor was trying to make, or your instructor was making his point very, very badly (which, frankly, is not uncommon, especially when it comes to teaching C).

Both of the malloc calls in your question are dynamic memory allocation. The only difference is that the first form allocates a known, fixed amount of memory every time it is executed, whereas the second can allocate a different amount each time it’s executed. That doesn’t make the first form not dynamic allocation.

The memory in both cases can be resized with a call to realloc.

And as a stylistic note, you don’t have to cast the result of malloc in C1. It’s much less eye-stabby to write

p = malloc( 5 * sizeof *p ); 

or

p = malloc( n * sizeof *p );

sizeof *p is the same as sizeof (int) (assuming p was declared as int *p). This makes maintenance easier, since you don’t have to repeat type information multiple times.


  1. That’s not the case in C++, but if you’re writing C++ you shouldn’t be using malloc anyway.
Sandry answered 3/8, 2020 at 13:4 Comment(0)
M
3

I was told by an instructor that p = (int*)malloc(5 * sizeof(int)); is NOT dynamic memory allocation and that p = (int*)malloc(n * sizeof(int)); is dynamic memory allocation

This is a somewhat opinion based issue in the sense that there is no obligation to refer to it as one or the other, this is largely based on convention. That said, I don't agree at all with the opinion that there is some correctness to the statement, even assuming the reference may be to the size of the memory block being deppendant on a constant value.

Both expressions should only be qualified as dynamic memory allocations either if you use a constant or a variable value. Stating otherwise can only be qualified as wrong, in my opinion.

Both memory block assignments can still be changed later on, in a runtime environment, they are therefore dynamic, whereas in an array declaration i.e.int arr[100] the assigned memory is fixed, it cannot be changed, thus it's not dynamic.

There are, however, differences in using a constant or a variable, for the obvious one, being able to assing a value to the variable that will determine the size of the memory block at runtime. And as @cmaster-reinstatemonica very accurately pointed out, using a constant as a size determinant for the memory block allows for compiler optimization of malloc in certain circumstances, which is meaningful given the fact that it can be an expensive function.

Other than that, the statements are largely similar. In both cases you can resize the memory blocks at runtime after the allocation.

Some good considerations regarding the correct usage of malloc are made by @JohnBode, I strongly recommend you follow them, in fact the entire answer is very good and should be called to the attention of your instructor if you feel comfortable with it, you'll be able to clarify the issue.

Mold answered 3/8, 2020 at 12:40 Comment(5)
The word dynamic may be applied at two different levels: 1) The object is allocated at run time, and 2) the object size is determined at run time. You use the first interpretation of the word (which is the usual consensus), the instructor used the second interpretation.Hartung
@cmaster-reinstatemonica, Yes your point is certainly correct, but the terms of the question are clear, p = (int*)malloc(5 * sizeof(int)); is NOT dynamic memory allocation, it is the memory allocation that is being qualified as not dynamic, not the the variable value which will determine the size. In that sense I must reject the statement.Mold
Well, the trouble is that not all people speak/read as precisely as you do. Nevertheless, they have intentions, and it's often useful to understand an instructors intention even when they use an incorrect way of expressing themself.Hartung
@cmaster-reinstatemonica But I'd say even both fixed- and variable-sized calls to malloc() are dynamic because the requested allocation is not guaranteed to succeed. Different results at different times -> dynamic.Mcghee
@AndrewHenle I fully agree. I would always call malloc(5) dynamic memory allocation. I was merely pointing out what the teacher was likely intending to communicate.Hartung

© 2022 - 2024 — McMap. All rights reserved.