You have undefined behavior. Be very scared. Read Lattner's blog on UB.
printf("%s",name);
This works when name
is a genuine string (that is some licit and valid memory zone ending with a zero byte). In your program it is not, you are accessing at least one byte past the malloc
-ed zone. You have a buffer overflow.
The only case for a single-char zone when it is a valid string is when that single char
contains a zero byte so the string is empty.
The above code perfectly stores a whole string
You just have bad luck (BTW, it is not "perfectly"). It could be worse (e.g. the collapse of the universe) and it could be better (e.g. some segmentation violation, nasal demons, ....). This is why you should be afraid of UB.
(to explain what happened on your particular computer, you need to dive into implementation details, e.g. study your operating system, your compiler, your instruction set, the assembler code generated by your compiler, etc etc...; you don't want to spend years of work on that, and even if you did it stays UB)
You should compile with all warnings and debug info (gcc -Wall -Wextra -g
) and use the debugger gdb
, valgrind and be sure that every memory location your program is dealing with is valid.
BTW malloc
could fail, and you should test against that and sizeof(char)
is by definition 1. You should try
char* name = malloc(80);
if (!name) { perror("malloc"); exit(EXIT_FAILURE); };
Please also read the documentation of every function you are using. Start with printf and malloc and scanf. Notice that your use of scanf
is dangerous. Better end your printf
control strings with a \n
or use fflush appropriately (since stdout is often line-buffered). Also download and study the specification n1570 of the C11 programming language.
On some systems, you have more than what the C11 standard guarantees. For example POSIX has getline
and you could use it like here. Consider also fgets (in the C11 standard) if you don't have a POSIX system (then you would need complex tricks to read arbitrarily long lines, or else specify and document that your program can only handle lines of at most 79 bytes if using malloc(80)
).
It is good manners to avoid arbitrary limits in your code; of course your computer still has limitations (you probably won't be able to handle a line of a hundred billion bytes).
Be aware of character encoding (see also this). Use today, in 2017, UTF-8 everywhere (e.g. with the help of libunistring or of glib) but then remember that a Unicode character can span several bytes (that is char
-s).