Perlin Noise Generator I'm porting a 2-D Terrain Generator from Python to C++ as Python is too slow due to the number of features that have been added.

I'm new to C++ and would like to know of any criticisms that you can make of the code at this time before I continue with the simpler parts of the generation.  Right now I'm interested in maintaining my use of arrays rather than std::vector so any improvements besides that would be greatly appreciated.

I'm also aware that this code is currently uncommented, I intend to fix that in the future however right now I'm more interested in the code itself.

#include "stdafx.h"
#include &lt;iostream&gt;
#include &lt;conio.h&gt;

double** white_noise(int w, int h);
double** smooth_noise(double** noise, int w, int h, int octave);
double** perlin_noise(double** noise, int w, int h, int octaves, double persistance);
double interpolate(double a, double b, double alpha);

int main()
{
    const int w = 400;
    const int h = 400;

    double** noise = white_noise(w, h);
    double** perlinnoise = perlin_noise(noise, w, h, 8, 0.7);

    // Code that does things will go here(function calls to add sea-level etc.)

    for (int i = 0; i &lt; w; i++) {
        delete[] noise[i];
        delete[] perlinnoise[i];
    }
    delete[] noise;
    delete[] perlinnoise;
}


double** white_noise(int w, int h) {
    double** noise = new double*[w];
    for (int i = 0; i &lt; w; i++) {
        noise[i] = new double[h];
    }

    for (int i = 0; i &lt; w; i++) {
        for (int j = 0; j &lt; h; j++) {
            noise[i][j] = (float)rand() / RAND_MAX;
        }
    }

    return noise;
}

double** smooth_noise(double** noise, int w, int h, int octave) {
    double** smooth_noise = new double*[w];
    for (int i = 0; i &lt; w; i++) {
        smooth_noise[i] = new double[h];
    }

    int period = 1 &lt;&lt; octave;
    double frequency = 1.0 / period;

    for (int i = 0; i &lt; w; i++) {
        int sample_i0 = i / period * period;
        int sample_i1 = (sample_i0 + period) % w;
        double horizontal_blend = (i - sample_i0) * frequency;

        for (int j = 0; j &lt; h; j++) {
            int sample_j0 = j / period * period;
            int sample_j1 = (sample_j0 + period) % h;
            double vertical_blend = (j - sample_j0) * frequency;

            double top = interpolate(noise[sample_i0][sample_j0],
                noise[sample_i1][sample_j0],
                horizontal_blend);
            double bottom = interpolate(noise[sample_i0][sample_j1],
                noise[sample_i1][sample_j1],
                horizontal_blend);
            smooth_noise[i][j] = interpolate(top, bottom, vertical_blend);
        }
    }

    return smooth_noise;
}

double** perlin_noise(double** noise, int w, int h, int octaves, double persistance) {
    double** perlin_noise = new double*[w];
    for (int i = 0; i &lt; w; i++) {
        perlin_noise[i] = new double[h];
    }
    for (int i = 0; i &lt; w; i++) {
        for (int j = 0; j &lt; h; j++) {
            perlin_noise[i][j] = 0;
        }
    }

    double*** smooth_noises = new double**[octaves];
    for (int i = 0; i &lt; octaves; i++) {
        smooth_noises[i] = smooth_noise(noise, w, h, i);
    }

    double amplitude = 1;
    double totalamplitude = 0;

    for (int octave = octaves - 1; octave &gt; 0; octave--) {
        amplitude *= persistance;
        totalamplitude += amplitude;

        for (int i = 0; i &lt; w; i++) {
            for (int j = 0; j &lt; h; j++) {
                perlin_noise[i][j] += smooth_noises[octave][i][j] * amplitude;
            }
            delete[] smooth_noises[octave][i];
        }
        delete[] smooth_noises[octave];
    }
    delete[] smooth_noises;

    for (int i = 0; i &lt; w; i++) {
        for (int j = 0; j &lt; h; j++) {
            perlin_noise[i][j] /= totalamplitude;
        }
    }

    return perlin_noise;
}

double interpolate(double a, double b, double alpha) {
    return a * (1 - alpha) + alpha * b;
}
Here are some things that may help you improve your code.

Strive for portable code

Several of the features of this code are either platform-specific or compiler-specific or both.  Specifically, #include &lt;conio.h&gt;, and #include "stdafx.h" both non-standard.  Further, neither are actually used so I would strongly recommend omitting them.

Prefer to avoid using new and delete directly

In modern C++, it's usually better to avoid explicit calls to new and delete.  In particular, it seems that the goal of this program is to create the perlinnoise matrix.  It is not clear whether you're intending to also use the noise array or if it's just a byproduct of the production of the perlinnoise array.   In any case, use of raw new and delete tends to lead to the problem mentioned in the next suggestion.

Consider using a better random number generator

You are currently using 

noise[i][j] = (float)rand() / RAND_MAX;


However, that's the old C way to do things.  better solution, if your compiler and library supports it, would be to use the C++11 `std::uniform_real_distribution.  It looks complex, but it's actually pretty easy to use, as I'll demonstrate below.

Don't leak memory

If you use new and delete directly, you must take care to make sure they match in every instance.  This is quite easy to get wrong, and in fact, this code gets it wrong.  In particular, the perlin_noise routine leaks memory.  Track how long it takes you to find and fix the problem, and then compare it to the following suggestion.

Use objects

C++ is an object-oriented language and accomodating and encouraging that style of design is one of the key benefits of using C++.  For that reason, and because it makes your program cleaner, easier to maintain, easier to re-use and less prone to error, I'd highly recommend using objects for this program.  

Use the Standard Template Library

There is a lot of functionality already available to you if you use the Standard Template Library (STL).  To illustrate this and a number of the previous points, here is a rewrite of your white_noise routine as an object.  First, we need a way to initialize it with random values, and then a way to address individual noise values by index.  This is easily done by deriving a WhiteNoise object from a std::valarray.

struct WhiteNoise : public std::valarray&lt;double&gt;
{
    WhiteNoise(int w, int h) :
        std::valarray&lt;double&gt;(w*h), 
        width{w},
        height{h}
    {
        std::mt19937 gen;
        std::uniform_real_distribution&lt;double&gt; dis;
        for (auto &amp;value : *this) {
            value = dis(gen);
        }
    }
    int width;
    int height;
};


Note that there is no explicit call to new or delete and that the width and height are embedded into the object rather than separate quantities.  If you create a similar PerlinNoise object, the main function could look like this:

int main()
{
    const int w = 400;
    const int h = 400;

    WhiteNoise wn(w,h);
    PerlinNoise pn(wn, 8, 0.7);

    // Create a bitmap just so that we have something to look at.
    makePGM(pn, "perlin.pgm");
}


The result: no memory leak and a much shorter, cleaner program (also faster in my testing, but you should test it on your machine).  The makePGM is just a function I wrote to create a bitmap image to visualize the result.