Actually memory management in C is super easy. When you need memory, you allocate it. When you are done with it, you free it.
Easy, right?
No: what semas "easy" is the operation to allocate or free memory. But it's not as easy as you think: let's remember that it is very unsafe (see the huge problem of buffer overruns and unsafe pointer aliasings which are very hard to formulate, as C has no native enforcement of type safety, memory barriers, immutability. As well it's not easy to determine the size to allocate and programs have to do themselves complex calculation.
Other languages offer much
And it's impossible in C to track the usage of allocated memory (see there's the wellknown problem of memory leaks). C offers two basic ways to allocate and free any memory block you want does offers no way to determine when this can be done. There's no protection at all, and bugs in unchecked decisions made by programmers are not detected, causing security risks everywhere. So programs allocate much more memory than what they need, then programs terminate and flush everything in a process using lazy strategies. Everything has to be reloaded. finally this is very inefficient.
Other languages offer great tools: notably gargage collectors (which are now damn fast and can radically reduce the footprint on the system, while keeping programs safe). Programmers no longer have to manage memory themselves, Data can be reused more easily, system memory will be allocated on demand, unallocated in the background when needed and only when it is safe.
The two basic C API malloc/free are just building blocks to create safe memory managers. But they are overused in applications (and let's not speak about the infamous C arrays which are very poor types, in fact not types at all, as they are in fact just using very unsafe pointer aliasing everywhere, causing major difficulties for compilers that cannot track data usage at all). Good old arrays in BASIC or Pascal are much safer (at least they are checked!) and in BASIC arrays are extensible without difficulties (no need to manage reallocs, but you can enforce a mximum size, which is the default behavior for DIM declarations in BASIC or ARRAY[1..N] in Pascal, but arrays in C are non-sense as they are never checked, always used via pointer aliases that never track the effective size of the array, so C functions not only have to pass array pointers, they have to track and pass themselves the usable size and nothing in the language will prevent pointers to be misused outside the safe range).
Tables or collections in PHP, Lua, Perl, Python or _javascript_, in Java offer the same level of isolation and protection (without the need for programmers to manage their size, and reallocations): these languages are MUCH simpler than C/C++ (C++ has added the capability of collections with libraries, but they are still not really standardized and not part of the core language, only part of a proposed "standard library" whose usage is not required and enforced by the language, so they still suffer from the problem of unchecked pointer aliasing).