Reputation: 8241
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
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
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