#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
char wd[10];
if(getcwd(wd,BUFSIZ) == NULL){ //BUFSIZ = 8192
perror("getcwd");
exit(1);
}
printf("wd = %sn",wd);
}
This C code works well in Ubuntu Linux 20.
The size of buffer wd is 10 but if I print the wd, it can output a string that is over size 10.
I think that the function uses the pointer of wd regardless of size, so it can work well but it can also print dummy string. Is it right?
//Edit :
printf("wd2 = %sn",wd2); -> printf("wd = %sn",wd);
2
Answers
Alright, let’s get you straightened out:
wd
aschar[10]
and then try and read8192
bytes into it — won’t work,You can’t declarewd
and then try and outputwd2
— won’t work, and your compiler should be screaming errors at you,,\n
is a literal"n"
(two\
are a literal''
) not a newline'n'
#include <limits.h>
and#define _GNU_SOURCE
to makePATH_MAX
available — which is the maximum length a pathname can be on your system (if any) — then read that many bytes withgetcwd()
.Putting it altogether, you can do:
Compile
With the source in
getcwd.c
and ALWAYS compiling with FULL WARNINGS ENABLED, you can do:(note: I have a
bin
directory in my current directory that I put executables in to keep from cluttering my source directory)Don’t accept code until it compiles without warning. Add
-Werror
to treat warnings as errors so you can’t cheat.Example Use/Output
Running the program yields:
Let me know if you have further questions.
You lie to
getcwd
about buffer size.getcwd
does not magically know the buffer size. Buffers which know their own size is not a C language feature. That’s whygetcwd
needs the size parameter!So,
getcwd
happily writes beyond end of array.In C, this is Undefined Behavior. Anything can happen, and "anything" includes what you observe here.