Why can't I use strerror?
strerror
is deprecated because it's not thread-safe. strerror
works on an internal static buffer, which may be overwritten by other, concurrent threads. You should use a secure variant called strerror_s
.
The secure variant requires that the buffer size be passed to the function in order to validate that the buffer is large enough before writing to it, helping to avoid buffer overruns that could allow malicious code to execute.
Why can't the result of strerror() be returned
You are missing the inclusion of the <string.h>
header file.
Documentation.
The compiler even tells you what exactly your problem is:
return makes pointer from integer without a cast
If there's no prototype present for a function, then it's assumed to return int
. And it appears that on your platform, a pointer to char
does not fit into an int
, hence its truncated, and then printf()
tries to dereference the thus invalid pointer.
Do I need to free the result of strerror() in C?
Not only do you not need to; you must not. The only things you can pass to free
are pointers to memory you obtained by malloc
or a function specified to return memory obtain by malloc
or "as if by malloc
". There is no such text in the specification of strerror
, so passing the string it returns to free
would produce undefined behavior. In particular, if the implementation uses malloc
internally to obtain the memory, you would be freeing that memory out from under it, causing it to perform use-after-free or double-free, which are some of the most dangerous types of memory bugs.
In practice, strerror
usually returns immutable strings from libc .rodata
or from a mmap
ped translation file, and it's likely that the error would immediately be caught as a crash.
Why doesn't strerror return a const-qualified pointer?
Same as for the type of string literals: It was already like that in C89, describing a practice dating back to before the introduction of const
in the language. Changing it would make current valid program invalid.
perror and strerror with close(2) involved
Standard error is where error messages are supposed to be printed. So perror()
prints its error message on standard error. If you close standard error, it can't print the message.
Why is "main: Success" printed? Shouldn't every directory have the "." dir that can be opened?
Yes, it does. You didn't get an error when calling fopen()
, so errno == 0
, and the message for this is Success
.
If you want to print an error message when fopen()
fails, you need to test for NULL
:
if (fopen(".") == NULL) {
printf("main: %s \n", strerror(errno));
}
Note that when opening files, the FD that's used is the lowest available FD. Since you've closed FD 2, that will most likely be used when opening .
. So standard error now points to the .
directory, which you can't write to, and perror()
will get an error when it tries to write there. But it can't report this error (where would it report it?).
Why can't I save the numeric value of errno?
The call to printf
or possibly strerror
itself reset* the errno
variable so the second printf
prints the result of the first one, not read
. Good practice is to save it as soon as possible, before any other function call.
Correct example:
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(){
errno=EPERM; // An example
int read_errno = errno;
printf("errno was %s\n", strerror(read_errno));
printf("errno was %s\n", strerror(read_errno));
}
Output:
errno was Operation not permitted
errno was Operation not permitted
*They do not have to reset it, furthermore successfull call to strerror
must not modify it.
Related Topics
C++ Bitfield Packing with Bools
Purpose of Explicit Default Constructors
Qt "Private Slots:" What Is This
How to Determine the Correct Size of a Qtablewidget
Shift Image Content with Opencv
C++ Bitfield Packing with Bools
Google Protocol Buffers Compare
Call of Overloaded Function Is Ambiguous
Compiling and Running a C++ Program with Vim
Is Std::Vector<T> a 'User-Defined Type'
Undefined Reference to Winmain@16 C++, Sdl-2
Meaning of Default Initialization Changed in C++11
Compile Time Template Instantiation Check
Determining If an Unordered Vector<T> Has All Unique Elements