😊
Cのdirnameについて
C言語のdirnameやbasenameは与える引数を破壊するみたいです。
#include <stdio.h>
#include <stdlib.h>
#incldue <libgen.h>
int main(int argc, char** argv)
{
if(argc == 2) {
char* dir_name = dirname(argv[1]);
puts(argv[1]);
puts(dir_name);
}
exit(0);
}
これは期待通りの値を表示しません。
中身を考えるとdirnameの戻り値はヒープに確保するのではなく引数のスタックを使っている
みたいです。
正しくは
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>
#include <limits.h>
#incldue <string.h>
int main(int argc, char** argv)
{
if(argc == 2) {
char fname[PATH_MAX];
strncpy(fname, argv[1], PATH_MAX);
char* dir_name = dirname(fname);
puts(argv[1]);
puts(dir_name);
}
exit(0);
}
なはずです。確認してませんが。つまりdirnameの戻り値は引数のスタックのメモリを使っているということです。メモリはどこかに確保しないといけないため、ヒープを使うか、スタックのメモリを使うかしかありませんが、スタックのメモリを使っているみたいです。その代わり戻り値をfreeする必要がないです。
拙作のコンパイラでは以下のように回避しました。
#include <neo-c2.h>
int main(int argc, char** argv)
{
if(argc == 2) {
char* dir_name = dirname(string(argv[1]));
puts(argv[1]);
puts(dir_name);
}
exit(0);
}
stringでヒープにメモリを確保してます。BoehmGCが管理するヒープです。
Discussion