<p>I can't help but to notice that not all <code>str*</code> functions have <code>mem*</code> counterparts, even when <strong>having them would make logical sense</strong>. Of course, a <code>memlen()</code> function would make absolutely 0 sense.</p>
<p>But why doesn't C have <code>memmem()</code> to find a needle of a specified length in a haystack of a specified length? This sounds a lot more useful and versatile to me than <code>strstr()</code> which only works on strings. If anything the former should be included and not the latter, because the <code>strstr()</code> could just be implemented as <code>memmem(needle, strlen(needle), haystack, strlen(haystack))</code>.</p>
<p>Another example of such a function would be <code>memrchr()</code>.</p>
<p>But it's <code>strstr()</code> that C has and not <code>memmem()</code>. Why might that be? Why don't all the <code>str*</code> functions have logical <code>mem*</code> counterparts?</p>

<c><standard-library>
Why doesn't C's standard library have functions for searching memory like strings?
CC BY-SA 4.0
2023-06-28T20:18:01.217Z
Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.
Community Compiler
CC BY-SA 4.0
2023-06-28T20:45:31.267Z
I don’t think you are likely to find any satisfying answer to this question. The reasons are almost certainly not because of any particular principle so much as “because that was what they needed for the programs they were writing so that was the way they did it”.
Alexis King
CC BY-SA 4.0
2023-06-29T06:46:23.877Z
Note that glibc and others have a memmem(const void*,size_t,const void*,size_t), using a very similar horspool algorithm as their strstr(const char*,const char*) with the main difference being the NUL detection necessary for strstr. Back when C was standardized, it was probably just not common to need one and such not widespread.
PlasmaHH
CC BY-SA 4.0
2023-06-30T14:40:45.747Z
`memmem` is also scheduled to be included in the next version of POSIX.1. https://www.austingroupbugs.net/view.php?id=1061 proposed the addition, and you can find `memmem` in the draft [*"Additional APIs for the Base Specifications Issue 8, Part 1"*](https://www.opengroup.org/austin/docs/austin_1110.pdf) document.
AJM
CC BY-SA 4.0
2023-06-30T14:41:47.597Z
https://www.opengroup.org/austin/docs/austin_842.txt noted a difference in the behaviour of Solaris's `memmem` compared to the versions in glibc/BSDs. https://www.opengroup.org/austin/docs/austin_847.txt confirmed that Solaris devs were willing to change that behaviour (as were HP-UX and AIX devs - so presumably their implementations were also discovered to behave like Solaris's). This allowed a consensus on the standardised `memmem` to be reached.
AJM
CC BY-SA 4.0
2023-12-09T18:33:39.447Z
A bit late, but I’ve closed this question as off-topic, as it [does not meet our standards for what constitutes an on-topic question about a standard library](https://langdev.meta.stackexchange.com/a/433).
Alexis King
<p>I have no particular insight into decisions made by the designers of the C standard library, but I can offer some informed speculation.</p>
<p>A C string is a (null-terminated) array of characters. That is, the elements in the array are a known size, the size of a character. On the other hand, a block of memory could represent anything, and even if it is an array, the <a href="https://en.wikipedia.org/wiki/Array_(data_structure)#One-dimensional_arrays" rel="noreferrer">stride</a> of the array could be arbitrary. And the things in the array might make sense to compare bit-for-bit, or they might not (i.e. two values might be logically equal even if they don't have the same bit pattern).</p>
<p>So your proposed linear search functions would make sense <em>if</em> the block of memory represents an array of values which can be compared bit-for-bit, but they all need an extra argument for the array stride. And then the implementation of those functions would have a loop which increments the search address by that variable, which is less performant than incrementing by a compile-time constant, particularly incrementing by 1 for an array index.</p>
<p>So for performance reasons, it is better to write a linear search function that is specialised for the stride of the array you want to search.</p>

CC BY-SA 4.0
2023-06-28T21:07:10.300Z
2023-06-28T21:07:10.300Z
kaya3
CC BY-SA 4.0
2023-06-29T05:51:35.577Z
In particular, it is very likely that any `struct` will contain padding bits or bytes that are often filled with garbage rather than explicitly zeroed (and arrays can have similar padding between elements) -- thus bits in the raw data that do not participate in logical equality.  This is also why you can't rely on `memcmp`ing an array or struct with anything but a known previous `memcpy` -- other forms of assignment may or may not copy these padding bits.
Miral
CC BY-SA 4.0
2023-06-29T07:07:00.900Z
More precisely, in C structure assignment is allowed to do anything that behaves the equivalent of member-wise assignment -- this might actually be member-wise assignment (leaving padding unchanged), or `memcpy` (copying padding), or even some hybrid thereof. You can't make any assumptions and even if you test what your compiler happens to do today, circumstances might change. C++ is similar but it leans even harder toward member-wise behaviour given the possibility of copy constructors and overloaded operators.
Miral
CC BY-SA 4.0
2023-06-29T14:36:43.327Z
@Miral Very good point. I was thinking more like floating-point numbers, or integers represented as sign and magnitude, where `0 == -0` but they have different bit patterns; or not-necessarily-reduced fractions where `(6, 4)` and `(3, 2)` are logically equal. But padding is probably much more common, particularly now that every processor uses two's complement for integers.
kaya3
CC BY-SA 4.0
2023-06-29T15:01:24.347Z
Searching struct arrays for exact matches is not a common operation anyway -- usually you search for a particular member (e.g. search a phone book by name). On the other hand, it's not uncommon to search an array of integers.
Barmar
CC BY-SA 4.0
2023-09-08T20:40:33.107Z
Well-written code which works with strings will avoid using any `str*` functions other than `strlen`, and use `mem*` functions to act upon storage after measuring strings' lengths once.  A `memmem` function could be just as useful as `strstr` when working with strings, but for many tasks, string-search code that knows something about the data it will likely receive can be much more efficient when fed such data than any general-purpose function could be.
supercat
# Why doesn't C's standard library have functions for searching memory like strings?
Posted by: username_0 on 2023-06-28
I can't help but to notice that not all `str*` functions have `mem*` counterparts, even when **having them would make logical sense**. Of course, a `memlen()` function would make absolutely 0 sense.

But why doesn't C have `memmem()` to find a needle of a specified length in a haystack of a specified length? This sounds a lot more useful and versatile to me than `strstr()` which only works on strings. If anything the former should be included and not the latter, because the `strstr()` could just be implemented as `memmem(needle, strlen(needle), haystack, strlen(haystack))`.

Another example of such a function would be `memrchr()`.

But it's `strstr()` that C has and not `memmem()`. Why might that be? Why don't all the `str*` functions have logical `mem*` counterparts?
**Tags:** c standard-library
> **Comments:**
> **username_1**: Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.  
> **username_2**: I don’t think you are likely to find any satisfying answer to this question. The reasons are almost certainly not because of any particular principle so much as “because that was what they needed for the programs they were writing so that was the way they did it”.  
> **username_3**: Note that glibc and others have a memmem(const void*,size_t,const void*,size_t), using a very similar horspool algorithm as their strstr(const char*,const char*) with the main difference being the NUL detection necessary for strstr. Back when C was standardized, it was probably just not common to need one and such not widespread.  
> **username_4**: `memmem` is also scheduled to be included in the next version of POSIX.1. https://www.austingroupbugs.net/view.php?id=1061 proposed the addition, and you can find `memmem` in the draft [*"Additional APIs for the Base Specifications Issue 8, Part 1"*](https://www.opengroup.org/austin/docs/austin_1110.pdf) document.  
> **username_4**: https://www.opengroup.org/austin/docs/austin_842.txt noted a difference in the behaviour of Solaris's `memmem` compared to the versions in glibc/BSDs. https://www.opengroup.org/austin/docs/austin_847.txt confirmed that Solaris devs were willing to change that behaviour (as were HP-UX and AIX devs - so presumably their implementations were also discovered to behave like Solaris's). This allowed a consensus on the standardised `memmem` to be reached.  
> **username_2**: A bit late, but I’ve closed this question as off-topic, as it [does not meet our standards for what constitutes an on-topic question about a standard library](https://langdev.meta.stackexchange.com/a/433).  
---
## 1 answers
### Answer by username_5 on 2023-06-28. Score: 11
I have no particular insight into decisions made by the designers of the C standard library, but I can offer some informed speculation.

A C string is a (null-terminated) array of characters. That is, the elements in the array are a known size, the size of a character. On the other hand, a block of memory could represent anything, and even if it is an array, the [stride](https://en.wikipedia.org/wiki/Array_(data_structure)#One-dimensional_arrays) of the array could be arbitrary. And the things in the array might make sense to compare bit-for-bit, or they might not (i.e. two values might be logically equal even if they don't have the same bit pattern).

So your proposed linear search functions would make sense *if* the block of memory represents an array of values which can be compared bit-for-bit, but they all need an extra argument for the array stride. And then the implementation of those functions would have a loop which increments the search address by that variable, which is less performant than incrementing by a compile-time constant, particularly incrementing by 1 for an array index.

So for performance reasons, it is better to write a linear search function that is specialised for the stride of the array you want to search.
> **Comments:**
> **username_6** (2023-06-29): In particular, it is very likely that any `struct` will contain padding bits or bytes that are often filled with garbage rather than explicitly zeroed (and arrays can have similar padding between elements) -- thus bits in the raw data that do not participate in logical equality.  This is also why you can't rely on `memcmp`ing an array or struct with anything but a known previous `memcpy` -- other forms of assignment may or may not copy these padding bits.  
> **username_6** (2023-06-29): More precisely, in C structure assignment is allowed to do anything that behaves the equivalent of member-wise assignment -- this might actually be member-wise assignment (leaving padding unchanged), or `memcpy` (copying padding), or even some hybrid thereof. You can't make any assumptions and even if you test what your compiler happens to do today, circumstances might change. C++ is similar but it leans even harder toward member-wise behaviour given the possibility of copy constructors and overloaded operators.  
> **username_5** (2023-06-29): @Miral Very good point. I was thinking more like floating-point numbers, or integers represented as sign and magnitude, where `0 == -0` but they have different bit patterns; or not-necessarily-reduced fractions where `(6, 4)` and `(3, 2)` are logically equal. But padding is probably much more common, particularly now that every processor uses two's complement for integers.  
> **username_7** (2023-06-29): Searching struct arrays for exact matches is not a common operation anyway -- usually you search for a particular member (e.g. search a phone book by name). On the other hand, it's not uncommon to search an array of integers.  
> **username_8** (2023-09-08): Well-written code which works with strings will avoid using any `str*` functions other than `strlen`, and use `mem*` functions to act upon storage after measuring strings' lengths once.  A `memmem` function could be just as useful as `strstr` when working with strings, but for many tasks, string-search code that knows something about the data it will likely receive can be much more efficient when fed such data than any general-purpose function could be.  
---
