Removing multiple slashes from path
Here are some suggestions for how you might improve your code.

Use the appropriate #includes

This program fragment requires headers, which should be included:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;


Use const where practical

Because the validate_path function does not alter the passed string, the parameter should be declared const:

char *validate_path ( const char* path )


Don't make pointless copies of variables

When you pass a parameter to a function, it's a copy, so there's no reason for this line:

char* path_copy = path;


Just use path directly.

Check for NULL before dereferencing

The first thing the validate_path does is to pass path to strlen, but this results in undefined behavior if path isn't a '\0'-terminated string.  A simple safety check would be to check to see if it's a NULL pointer and exit if it is.

Consider a change to the interface

Instead of allocating memory within the function, consider instead altering the function so that it is passed an input and output buffer.  This way, the code would not need to allocate memory and the caller would do both allocation and freeing.  That makes for a more robust interface and it makes your code simpler.

Prefer for to while

The while loop within the code would likely be more succinctly expressed as a for loop.  That way it's easier to see what is being iterated through and how.

Use a more accurate function name

I would expect that validate_path would do just that and validate a path, but that's not really what's happening here.  Instead, it seems that a more accurate function name would be something like remove_dup_slashes.

Simplify your code

Here's an alternative implementation that uses these suggestions:

char *validate_path(const char *path, char *curr) {
    if (path == NULL || curr == NULL) {
        return NULL;
    }
    char *begin = curr;
    // always copy first character
    *curr = *path;
    // if it's just a single `NUL`, we're done
    if (*curr == '\0') {
        return curr;
    }
    for (path++; *path; ++path) {
        // path points to next char to read
        // curr points to last written
        if (*curr != *path || (*curr != '\\' &amp;&amp; *curr != '/')) {
            // only copy if not duplicate slash
            *(++curr) = *path;
        }
    }
    *curr = '\0';  // terminate string
    return begin;
}


Note that the interface is still not a very good one.  It could be improved by also passing in the length of the output buffer and maybe the length of the input buffer as well.