69

I wonder, why such function as:
-memset
-memmov
-memchr
-memcpy

Exist in string.h header file, but not in stdlib.h file, where there are other standard memory functions as dynamic memory allocation: malloc, calloc, realloc, free.

Maybe it would be better to unite them in one header? What do you think about it? I don't understand, why one set of memory functions are separated from others and exist in string header ( string.h ).

Rndp13
  • 1,094
  • 1
  • 21
  • 35
  • 1
    This looks like implementation issue with the C library you are using. Other C library may choose to move memcpy to stdlib. – AgA Mar 20 '12 at 06:22
  • 2
    `malloc` and family deal with dynamic memory allocation. `memcpy` and family deal with sequences of bytes. `strcpy` and family also deal with sequences of bytes, in a slightly different way. – n. m. could be an AI Mar 20 '12 at 06:22
  • 9
    @AgA: If a C library conforms to the ISO standard then `memcpy` is going to be in `string.h`, not `stdlib.h`. – Blastfurnace Mar 20 '12 at 06:29
  • 1
    My guess, it's purely historical reasons. That was probably the header file the function was put in when they were first introduced, and to keep maximum backward compatibility the standard committee decided to let them stay there. – Some programmer dude Mar 20 '12 at 06:53
  • 7
    The C standard library is not a model of consistent design. – Keith Thompson Mar 20 '12 at 06:57

4 Answers4

43

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.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • 4
    but such methods as memset, memchr, memmov, memcpy work with void* type and really more works memory not char, am I right? –  Mar 20 '12 at 06:49
  • 3
    You can pass any object pointer type, but the array elements are in fact interpreted as if they have the type `unsigned char`. (C99, 7.21.1p3) – ouah Mar 20 '12 at 06:55
  • 2
    Also regarding `void *`, note that in K&R C (pre-Standard C), there was no `void` type and the parameters of functions like `memcpy` and `memset` were of `char *` type and not `void *`. – ouah Mar 20 '12 at 07:11
13

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.

Ken Wayne VanderLinde
  • 18,915
  • 3
  • 47
  • 72
4

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.

Leandros
  • 16,805
  • 9
  • 69
  • 108
2

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.