String join function C char* join(char** strings, size_t num_strings, char* seperator)
{
    int cache = 0;
    int count = 0;
    for(int i = 0; i &lt; num_strings; i++){
        cache += strlen(strings[i]);
    }
    char * joined = malloc((cache + num_strings * strlen(seperator) + 1) * sizeof(char));
    for(int j = 0; j &lt; num_strings; j++){ //big loop
        if(j != 0){
            int j = 0;
            while(j &lt; strlen(seperator)){ //inserting seperators
                joined[count] = seperator[j];
                count++;
                j++;
            }
        }
        int insert_string = 0;
        while( insert_string &lt; strlen(strings[j])){ //inserting strings
            joined[count] = strings[j][insert_string];
            insert_string++;
            count++;
        }
    }
    joined[count] = 0; //Zero Termination
    return joined;
}


I wrote this join() function, which creates a string from num_strings with specified separator, for example *. Is there a way to make this more concise?  Also is the termination correct?
char* join(char** strings, size_t num_strings, char* seperator)


The inputs can be const as they should not be modified by this function: const char* join(const char** strings, size_t num_strings, const char* seperator)


int cache = 0;


cache is not a very descriptive name. Prefer input_strings_length or similar


for(int i = 0; i &lt; num_strings; i++){


Format as for (int i = 0; i &lt; num_strings; i++) { (added spaces for readability)


char * joined


Why does the * have spaces around both side, but the rest are char* name? (space only on right side)


for(int j = 0; j &lt; num_strings; j++){
    if(j != 0){
        int j = 0;


Prefer not using shadowed variables (same variable name in both inside and outside)


int j = 0;
while(j &lt; strlen(seperator)){ //inserting seperators
    joined[count] = seperator[j];
    count++;
    j++;
}


This is same as:
strcpy(joined + count, seperator);
count += strlen(seperator);

which I find more readable


// big loop


This comment is not descriptive at all. What does it mean?
I would rename variable in for(int j = 0; j &lt; num_strings; j++){ to be for (int string_index = 0; string_index &lt; num_strings; string_index++) {

The whole program:
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

const char * array[] = {
    &quot;First entry&quot;,
    &quot;Second entry&quot;,
    &quot;Third entry&quot;,
};

const char* join(const char** strings, size_t num_strings, const char* seperator) {
    int input_strings_length = 0;
    for (int i = 0; i &lt; num_strings; i++) {
        input_strings_length += strlen(strings[i]);
    }

    size_t string_length = input_strings_length + num_strings * strlen(seperator);
    char* joined = malloc((string_length + 1) * sizeof(char));
    joined[string_length] = '\0';

    int array_offset = 0;

    for (int string_index = 0; string_index &lt; num_strings; string_index++) {
        if (string_index != 0) {
            strcpy(joined + array_offset, seperator);
            array_offset += strlen(seperator);
        }

        strcpy(joined + array_offset, strings[string_index]);
        array_offset += strlen(strings[string_index]);
    }

    return joined;
}

int main() {
    printf(&quot;%s\n&quot;, join(array, 3, &quot;SEP&quot;));
    return 0;
}