Me pregunto, ¿por qué tal función como:
-memset
-memmov
-memchr
-memcpy
Existe en el archivo de encabezado string.h, pero no en el archivo stdlib.h, donde hay otras funciones de memoria estándar como asignación de memoria dinámica: malloc, calloc, realloc, free.
¿Quizás sería mejor unirlos en un encabezado? ¿Qué piensa usted al respecto? No entiendo por qué un conjunto de funciones de memoria está separado de otros y existe en el encabezado de cadena ( string.h ).
ouah
porque en realidad string.h
se define como un encabezado estándar que declara funciones que tratan una matriz de caracteres y no solo cadenas. Funciones como memcpy
y memset
tomar argumentos que se tratan como punteros al primer elemento de un objeto de tipo matriz de caracteres.
(C99, 7.21.1p1) El encabezado
declara un tipo y varias funciones, y define una macro útil para manipular matrices de tipo de carácter y otros objetos tratados como matrices de tipo de carácter.
-
pero métodos como memset, memchr, memmov, memcpy funcionan con el tipo void* y realmente funcionan más con la memoria que con el char, ¿verdad?
– usuario1131997
20 de marzo de 2012 a las 6:49
-
Puede pasar cualquier tipo de puntero de objeto, pero los elementos de la matriz se interpretan de hecho como si tuvieran el tipo
unsigned char
. (C99, 7.21.1p3)– ouah
20 de marzo de 2012 a las 6:55
-
También con respecto a
void *
tenga en cuenta que en K&R C (pre-Standard C), no habíavoid
type y los parámetros de funciones comomemcpy
ymemset
eran dechar *
tipo y novoid *
.– ouah
20 de marzo de 2012 a las 7:11
Realmente no pensaría en el string.h
funciona como funciones de “memoria”. En cambio, pensaría en ellos como funciones de “matriz”, ya que operan en los datos que están contenidos dentro de las secuencias de memoria. Por el contrario, malloc
(y otros), en realidad brindan servicios de memoria como la asignación, en lugar de la manipulación de los datos dentro de una región de la memoria.
En particular, las funciones de string.h
no se ocupe de ninguna asignación o desasignación de memoria, ni de ninguna forma de administración de memoria. Incluso una función como char * strerror(int)
, que parece crear una cadena completamente nueva, no realiza ninguna asignación, porque el valor devuelto es en realidad una cadena asignada estáticamente. Las otras funciones pueden devolver un puntero a un bloque de memoria, pero en realidad es solo uno de sus parámetros (p. ej. memcpy
). O devuelven un puntero al comienzo de una subcadena (strtok
), o un número entero que representa una comparación (memcmp
).
Por otra parte, stdlib.h
tampoco se trata realmente de la memoria. el diseño de stdlib.h
es proporcionar operaciones de propósito general que probablemente necesitará una gran cantidad de programas. Las funciones de memoria resultan ser ejemplos de tales operaciones fundamentales. Sin embargo, otras funciones como exit
y system
también son buenos ejemplos, pero no se aplican a la memoria.
Ahora hay algunas funciones en stdlib.h
en el que se podría haber colocado a la OMI string.h
en particular las diversas funciones de conversión (mbstowcs
, wcstombs
, atoi
, strtod
etc.), y tal vez incluso el bsearch
y qsort
funciones Estas funciones siguen los mismos principios que las string.h
funciones (operan en matrices, no devuelven bloques de memoria recién asignados, etc.).
Pero desde una perspectiva práctica, incluso si tenía mucho sentido combinar los mem*
funciones con el malloc
, realloc
, calloc
y free
funciones, la biblioteca estándar de C es nunca va a ser reorganizado así. Tal cambio definitivamente rompería el código. También, stdlib.h
y string.h
han existido durante tanto tiempo, y son bibliotecas tan útiles y fundamentales, que los cambios probablemente romperían la mayoría (o al menos, mucho) del código C.
En Pre-Standard C, estas funciones fueron de hecho definidas en otro lugar, pero tampoco en stdlib.h
ni en ninguno de los otros encabezados estándar, sino en memory.h
. Todavía podría existir en su sistema, ciertamente todavía existe en OS X (a partir de hoy).
memory.h
en OS X 10.11 (sin encabezado de licencia):
#include <string.h>
Todo el archivo es sólo #include
‘En g string.h
para mantener la compatibilidad con versiones anteriores de los programas C anteriores al estándar.
Además de las consideraciones históricas, la separación de las utilidades de manipulación de datos como las de string.h
y funciones del sistema como malloc
en stdlib.h
tiene mucho sentido cuando considera contextos donde un sistema operativo no es un hecho. Los sistemas integrados pueden o no tener un RTOS y pueden o no tener una asignación de memoria estándar disponible. Sin embargo, utilidades como strcpy
y memcpy
ocupan un espacio similar en el sentido de que no dependen de ningún sistema externo y, por lo tanto, se pueden ejecutar en cualquier contexto en el que pueda ejecutar código compilado. Conceptual y prácticamente, tiene sentido juntarlos y separarlos de llamadas al sistema más complejas.
Esto parece un problema de implementación con la biblioteca C que está utilizando. Otra biblioteca C puede optar por mover memcpy a stdlib.
– AgA
20 de marzo de 2012 a las 6:22
malloc
y la familia se ocupan de la asignación de memoria dinámica.memcpy
y la familia trata con secuencias de bytes.strcpy
y la familia también tratan con secuencias de bytes, de una manera ligeramente diferente.– norte 1.8e9-dónde-está-mi-participación m.
20 de marzo de 2012 a las 6:22
@AgA: si una biblioteca C cumple con el estándar ISO, entonces
memcpy
va a estar enstring.h
nostdlib.h
.– Alto horno
20 de marzo de 2012 a las 6:29
Supongo que son razones puramente históricas. Ese fue probablemente el archivo de encabezado en el que se colocó la función cuando se introdujeron por primera vez, y para mantener la máxima compatibilidad con versiones anteriores, el comité estándar decidió dejarlos allí.
– Un tipo programador
20 de marzo de 2012 a las 6:53
La biblioteca estándar de C no es un modelo de diseño consistente.
–Keith Thompson
20 de marzo de 2012 a las 6:57