I want to preface this by saying that I’ve done very little programming in C, so I’d prefer to know why a given solution works rather than just what it is.
I’m trying to write a function which will take a pathname, and return a pathname to a different file in the same directory.
"/example/directory/with/image.png" => "/example/directory/with/thumbnail.png"
What I’ve tried after reading up on example uses of realpath and dirname (I’m working on Linux; if there’s a cross-platform equivalent, let me know) is:
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char *chop_path(char *orig) {
char buf[PATH_MAX + 1];
char *res, *dname, *thumb;
res = realpath(orig, buf);
if (res) {
dname = dirname(res);
thumb = strcat(dname, "/thumbnail.png");
return thumb;
}
return 0;
}
Compiling it seems to work, but running the program with
int main(void) {
char *res = chop_path("original.png");
if (res) {
printf("Resulting pathname: %s", res);
}
return 0;
}
gives me a segfault. Any hints?
The only problem I see is the signature of your
chop_pathroutine; it should beYour version has a missing
*. That makes an enormous difference actually; without the*, you’re effectively tellingdirnameandrealpathto interpret the character code of the first character in your argument string as the numerical address (i.e., a pointer to) the path. That’s going to point into a location in low memory that you definitely have not allocated; trying to use it results in that “segmentation fault” error, which means, effectively, that you’re trying to touch memory you’re not allowed to.The other issue turned out to be that the
dirname()function is declared inlibgen.h, which you weren’t including. If you don’t include that header, the compiler assumesdirname()returnsintinstead of a pointer, and on a 64-bit architecture, the 64-bit return value from the function gets chopped down to 32 bits, a bad pointer is assigned todname, and that’s going to cause your seg fault right there.