Why memory functions such as memset, memchr... are in string.h, but not in stdlib.h with another mem functions?

Because actually string.h is defined as a standard header that declares functions that treat array of characters and not only strings. Functions like memcpy and memset take arguments that are treated as pointers to the first element of an object of type array of characters.

(C99, 7.21.1p1) The header < string.h > declares one type and several functions, and defines one macro useful for manipulating arrays of character type and other objects treated as arrays of character type.


I wouldn't really think of the string.h functions as "memory" functions. Instead, I would think of them as "array" functions, since they operate on the data which is contained within sequences of memory. By contrast, malloc (and others), actually provide memory services such as allocation, rather than manipulation of the data within a region of memory.

In particular, the functions in string.h do not take care of any allocation or deallocation of memory, or any form of memory management. Even a function like char * strerror(int), which appears to create a whole new string, does not do any allocations, because the return value is actually a statically-allocated string. The other functions might return a pointer to a memory block, but this is actually just one of their parameters (e.g. memcpy). Or they return a pointer to the start of a sub-string (strtok), or an integer representing a comparison (memcmp).

On the other hand, stdlib.h is also not really about memory. The design of stdlib.h is to provide general-purpose operations which a large number of program will likely need. The memory functions just happen to be examples of such fundamental operations. However, other functions like exit and system are also good examples, yet don't apply to memory.

Now there are some functions in stdlib.h which IMO could have been placed in string.h, particularly the various conversion functions (mbstowcs, wcstombs, atoi, strtod, etc.), and maybe even the bsearch and qsort functions. These functions follow the same principles as the string.h functions (they operate on arrays, don't return newly allocated memory blocks, etc).

But from a practical perspective, even if it made a lot of sense to combine the mem* functions with the malloc, realloc, calloc and free functions, the C standard library is never going to be reorganized like this. Such a change would definitely break code. Also, stdlib.h and string.h have been around for so long, and are both such useful and fundamental libraries, that the changes would probably break most (or at least, a lot of) C code.


In Pre-Standard C, these functions were indeed defined somewhere else, but neither in stdlib.h nor in any of the other standard headers, but in memory.h. It still might exist on your system, it certainly still does on OS X (as of today).

memory.h on OS X 10.11 (without license header):

#include <string.h>

The whole file is only #include'ing string.h, to retain backwards compatibility with Pre-Standard C programs.


Besides historical considerations, the separation of data manipulation utilities like those in string.h and system functions like malloc in stdlib.h makes a lot of sense when you consider contexts where an operating system is not a given. Embedded systems may or may not have an RTOS and they may or may not have standard memory allocation available. However, utilities like strcpy and memcpy occupy a similar space in that they do not rely on any external systems and therefore can be run in any context where you can run compiled code. Conceptually and practically it makes sense to put them together, and to separate them from more complex system calls.