C - 2D peak finder in
Use standard array notation
When you are accessing array elements, the idiomatic way in C is to write foo[bar] instead of *(foo + bar). So instead of:
int next_number = *((i * rows + arr) + col);

Write:
int next_number = arr[i * rows + col];

It is both shorted, and now it is clear what part the array pointer is and what part the index is.
Avoid unnecessary memory allocations
It's perfectly possible in C to return a struct by value. This avoids having to call malloc() and free(), and you no longer have to worry about its memory leaking, nor have to check whether malloc() succeeded. You do it like so:
max_vector find_col_peak(int *arr, int rows, int col) {
    max_vector vector;

    // set max to the first item of the column
    vector.col_index = 0;
    vector.index_value = *(col + arr);

    ...

    return vector;
}

About recursion
With the above you don't have to worry about freeing memory for vector anymore. However, recursive calls themselves could have some memory overhead, since each call needs some amount of space on the stack. With this algorithm, you only need log2(cols) recursion levels, so that won't be an issue even for huge inputs. Also, the compiler can turn these recursive calls into tail calls.