Ryan
Ryan

Reputation: 8241

Getting bus error in function attempting to set character to '\0' in C string

I need to write a function in C that, given a path such as /usr/bin/wc, returns the parent directory of the file (this one would return /usr/bin). This is my attempt at doing this:

char *get_parent_dir(char *path) {
    char *head = path;
    int i = strlen(path) - 1;

    while (i > 0) {
        if (path[i] == '/') {
            path[i] = '\0';
            break;
        }
        i--;
    }

    return head;
}

However, upon running this with a test path, I get the following error: Bus error: 10.

Can anyone explain why this is, and what I could change to avoid getting this error?

Edit: my usage of the function is something like

char *full_path = "/usr/bin/wc";
get_parent_dir(full_path);

Upvotes: 0

Views: 188

Answers (2)

user3629249
user3629249

Reputation: 16540

regarding this line:

char *full_path = "/usr/bin/wc";

is setting char pointer full_path to point to a string literal.

Trying to change a string literal results in a seg fault event.

Try this instead:

char full_path[] = "/usr/bin/wc";

Which places the string in the local array full_path, where it can be modified.

Upvotes: 0

skyking
skyking

Reputation: 14400

You are effectively passing a string literal as argument to get_parent_dir, which reseluts in that the function tries to modify a string literal (that normally can't be modified). In the standard this means undefined behaviour (which means that the observed behavior is in line with what the standard prescribes). The exact symptom of this is depending on your operating system (and the compiler), here I get segmentation fault instead.

Already the modification of the parameter is questionable even if it were passed a mutable string. Normally one doesn't expect a function to modify strings that are passed to them. Instead I'd suggest that you allocate new space for the parent directory (but that too requires some care since the caller then is expected to free the result when done with it):

char *get_parent_dir(char *path) {
    char *head = strdup(path);
    int i = strlen(path) - 1;

    if( head == NULL )
         return NULL;

    path = head;

    while (i > 0) {
        if (path[i] == '/') {
            path[i] = '\0';
            break;
        }
        i--;
    }

    return head;
}

Upvotes: 4

Related Questions