まず、通常、文字列や数値などのデータはスタック領域(Stack area) に保存されます。
でも、このスタック領域、サイズが決まっており、整数一個とかなら問題ありませんが、
Webブラウザのタブみたいに複数必要だったり、構造体やクラスとかのような、物によっては相当デカいものだと、保持するのが大変です。
そこで、ヒープ領域(Heap area) と呼ばれる場所で、動的に確保する事で、メモリが許す限り保持できます。
ただし、これにも欠点があり、「自分でお片付けしないといけない」というのがあります。
スタック領域だと、関数のブロックから抜けるとかのような、「もうこれ以上使わんだろ」と思う場合は勝手にデリートされます。(返還される)
でも、ヒープ領域は開発者自身が「この領域にあるデータを破棄せよ」と命じないとずーーーーっと残ったままです。
(OSによっては実行ファイルが終了するとOS自身が破棄してくれるようですが)
その「ヒープ領域のここからこの分確保するぞ!」っていうのはC言語だとmalloc, C++だとnewに相当するものです。
「あー、(ヒープ領域の)ここにあるデータ、もう使わないから破棄だわ」というのがC言語だとfree, C++だと delete に相当するものです。
(ちなみにJavaとかのような言語だと、ガーベージコレクタ(GC)と呼ばれるものがdeleteしてくれるようです)
仮に、実行ファイルが閉じられるとOSがお片付けしてくれるとしても、
Webブラウザや常駐型のものだと、そこの部分はずーーーーーーっとあるので、メモリをひっ迫してしまいます。
なのでnewをするのなら、不必要になればdeleteするのがマナーです。
参考: メモリの動的確保(配列など)
そして、今回のコードですね。
今回のコードを見ると、
C++
1int buf = 100;
2
3int *nums = new int[buf];
となっていますね。
これは、動的にメモリ、つまりヒープ領域を確保しています。
で、最後は不要になったので、deleteで破棄。
要素数がはっきりとわかっている場合は普通の配列でもいいですが、要素数が実行時にしかわからないこともあります。
さらに、構造体やクラスの配列 ( Class1 objs[100] のような ) の場合もあります。
構造体やクラスなんかはメンバの分だけ重くなります。
(メンバ関数は関係ないっぽいが)
スタック領域だとその分ひっ迫します。
サイズによってはオーバーフローを起こします。
そのため、サイズが(実行するまで)不定だったり、オブジェクトのサイズがデカい場合はヒープ領域に確保する事があります。
int型とかだと 4バイトとかなのですが、構造体やクラスの場合はメンバ(メンバ変数)分、必要になるので、C++だとnew/deleteで確保する事が多いのです。
それを見習って(?) Javaとかでは new を使う方式でやるようです。
[追記1]
※ 他の回答者の方のアンサーを見て、ちょっと思ったので追記。
確かに単純にデータ列を確保するのなら new/deleteよりも std::vectorやstd::listを使ったりしますね。
ですが、クラスオブジェクトを生成する場合は良く使います。(モダンなものだとスマートポインタと呼ばれる、std::shared_ptr とかを使うようですが)
単純にint型データの配列のような場合はnew/deleteをするぐらいならstd::vectorを使います。