Q:

C Exception thrown when function is ran for a second time

This is core of the function i am currently writing.
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <ctime>
#include <cstring>

const char *words[] = {
    "pigu",
    // "third",
    // "country",
    // "human",
    // "define",
};
#define word_count (sizeof(words) / sizeof(char *))
const char *allowed_chars = "abcdefghijklmnopqrstuvwxyz";

const char *get_random_word()
{
    return words[rand() % word_count];
}

char *copy(const char *origin)
{
    char *str = NULL;
    str = (char *)malloc(sizeof(origin));
    strcpy(str, origin);
    return str;
}

int run()
{
    const char *selected_word = get_random_word();
    char *active_word = copy(selected_word);
    char *placeholder_word = copy(selected_word);
    char *left_chars = copy(allowed_chars);

    free(active_word);
    free(placeholder_word);
    free(left_chars);
    return 1;
}

int main(int argc, char *argv[])
{
    srand(time(NULL));
    while (run())
    {
    }
    printf("\n");
    return 0;
}

I have stripped out other code and managed to locate the problem to run function, which in this case will run infinitely, however while debugging I have set break points inside run function. Turns out that after running the function run for second time, the program crashes when it tries to execute free(placeholder_word);. Why is this happening and how could i prevent it.

A:

Your copy function is wrong, sizeof(origin) returns the number of bytes needed
to store a pointer in memory, not the length of the string. So you've allocated
the incorrect number of bytes and if the length of the string is longer than
sizeof(origin) - 1, then you would overflow the buffer, which leads to
undefined behaviour which would explain the segfault.
It should be
char *copy(const char *origin)
{
    char *str = NULL;
    str = malloc(strlen(origin) + 1);
    if(str == NULL)
        return NULL;
    strcpy(str, origin);
    return str;
}

Note that I've removed the cast of malloc, which is not needed in C. If you
need it because this is a C++ program, the use new instead of malloc.
And you should always check if malloc returns NULL before accessing the
memory.

