📄 stdlib.c
字号:
acc = ULONG_MAX;
errno = ERANGE;
} else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
/***************************************
*
* Math function
*
***************************************/
/**
* abs - compute the absolute value of an integer
*/
int abs(int j){
return j < 0 ? -j : j;
}
/**
* labs - compute the absolute value of an integer
*/
long int labs(long int j){
return j < 0 ? -j : j;
}
/**
* llabs - compute the absolute value of an integer
*/
long long int llabs(long long int j){
return j < 0 ? -j : j;
}
/***************************************
*
* Data Structure and Algorithm function
*
***************************************/
/**
* bsearch - binary search of a sorted array
*
* @desc The function searches an array of nmemb objects, the initial member of which is pointed to by base, for a member
* that matches the object pointed to by key. The size of each member of the array is specified by size
* @return The function returns a pointer to a matching member of the array, or NULL if no match is found. If there are
* multiple elements that match the key, the element returned is unspecified.
*/
void *bsearch (const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *)){
size_t l, u, idx;
const void *p;
int comparison;
l = 0;
u = nmemb;
while (l < u){
idx = (l + u) / 2;
p = (void *) (((const char *) base) + (idx * size));
comparison = (*compar) (key, p);
if (comparison < 0)
u = idx;
else if (comparison > 0)
l = idx + 1;
else
return (void *) p;
}
return NULL;
}
/**
* swap - swap two variables (for qsort)
*/
static void swap(void *base, size_t i, size_t j, size_t size){
void *tmp = malloc(size);
memcpy(tmp, (char *)base + i * size, size);
memmove((char *)base + i * size, (char *)base + j * size, size);
memcpy((char *)base + j * size, tmp, size);
free(tmp);
}
/**
* qsort - sorts an array
*
* @desc The function sorts an array with nmemb elements of size size. The base argument points to the start of
* the array
* @return The function returns no value
*/
void qsort(void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *)){
int i, last;
if (nmemb <= 1)
return;
swap(base, 0, nmemb / 2, size);
last = 0;
for (i = 1; i < nmemb; i++)
if (compar((char *)base + (i * size), base) < 0)
swap(base, i, ++last, size);
swap(base, 0, last, size);
qsort(base, last, size, compar);
qsort((char *)base + (last + 1) * size, nmemb - last - 1, size, compar);
}
/**
* srand - pseudo-random number generator
*
* @desc The function sets its argument as the seed for a new sequence of pseudo-random integers to be returned
* by rand(). These sequences are repeatable by calling srand() with the same seed value.
* If no seed value is provided, the rand() function is automatically seeded with a value of 1
* @return The function returns no value
*/
void srand(unsigned int seed){
__rand_next__ = seed;
}
/**
* rand - pseudo-random number generator
*
* @desc The function returns a pseudo-random integer between 0 and RAND_MAX.
* @return The functions return a value between 0 and RAND_MAX.
*/
int rand(void){
__rand_next__ = __rand_next__ * 1103515245 + 12345;
return (unsigned int)(__rand_next__ / 65536) % 32768;
}
/**
* rand - pseudo-random number generator
*
* @desc The function is supplied with a pointer to an unsigned int, to be used as state. This is a very small amount of
* state, so this function will be a weak pseudo-random generator.
* @return The functions return a value between 0 and RAND_MAX.
*/
int rand_r(unsigned int *seed){
unsigned int next = *seed;
int result;
next *= 1103515245;
next += 12345;
result = (unsigned int) (next / 65536) % 2048;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next / 65536) % 1024;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next / 65536) % 1024;
*seed = next;
return result;
}
/***************************************
*
* Memory control function
*
***************************************/
/**
* morecore - ask system for more memory (for malloc)
*
* @desc system implement (like UNIX os use sbrk() alloc data segment)
*/
static Header *morecore(size_t nu){
char *cp, *sbrk(int);
Header *up;
if (nu < NALLOC)
nu = NALLOC;
cp = sbrk(nu * sizeof(Header));
if (cp == (char *) -1) /* no space at all */
return NULL;
up = (Header *) cp;
up->s.size = nu;
free((void *)(up+1));
return freep;
}
/**
* malloc - Allocate dynamic memory
*
* @desc malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared. If
* size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed
* to free().
* @return malloc(), the value returned is a pointer to the allocated memory, which is suitably aligned for any kind of
* variable, or NULL if the request fails.
*/
void *malloc(size_t size){
size_t nbytes = size;
Header *p, *prevp;
size_t nunits;
nunits = (nbytes+sizeof(Header)-1)/sizeof(header) + 1;
if ((prevp = freep) == NULL) { /* no free list yet */
base.s.ptr = freeptr = prevptr = &base;
base.s.size = 0;
}
for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {
if (p->s.size >= nunits) { /* big enough */
if (p->s.size == nunits) /* exactly */
prevp->s.ptr = p->s.ptr;
else { /* allocate tail end */
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
return (void *)(p+1);
}
if (p == freep) /* wrapped around free list */
if ((p = morecore(nunits)) == NULL)
return NULL; /* none left */
}
}
/**
* free - Free dynamic memory
*
* @desc free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(),
* calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs.
* If ptr is NULL, no operation is performed.
* @return free() returns no value
*/
void free(void *ptr){
Header *bp, *p;
void *ap = ptr;
bp = (Header *)ap - 1; /* point to block header */
for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
break; /* freed block at start or end of arena */
if (bp + bp->size == p->s.ptr) { /* join to upper nbr */
bp->s.size += p->s.ptr->s.size;
bp->s.ptr = p->s.ptr->s.ptr;
} else
bp->s.ptr = p->s.ptr;
if (p + p->size == bp) { /* join to lower nbr */
p->s.size += bp->s.size;
p->s.ptr = bp->s.ptr;
} else
p->s.ptr = bp;
freep = p;
}
/**
* calloc - Allocate dynamic memory
*
* @desc calloc() allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allo-
* cated memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either NULL, or a
* unique pointer value that can later be successfully passed to free().
* @return the value returned is a pointer to the allocated memory, which is suitably aligned for any kind of variable,
* or NULL if the request fails.
*/
void *calloc(size_t nmemb, size_t size){
void *ptr;
ptr = malloc(nmemb * size);
if (ptr)
memset(ptr, '\0', nmemb * size);
return ptr;
}
/**
* realloc - Allocate dynamic memory
*
* @desc realloc() changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged
* to the minimum of the old and new sizes; newly allocated memory will be uninitialized. If ptr is NULL, the
* call is equivalent to malloc(size); if size is equal to zero, the call is equivalent to free(ptr). Unless ptr
* is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed
* to was moved, a free(ptr) is done.
* @return realloc() returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable
* and may be different from ptr, or NULL if the request fails. If size was equal to 0, either NULL or a pointer
* suitable to be passed to free() is returned. If realloc() fails the original block is left untouched; it is
* not freed or moved.
*/
void *realloc(void *ptr, size_t size){
Header *bp;
void *new_ptr;
size_t old_size;
if (ptr == NULL)
return malloc(size);
bp = (Header *)ptr - 1; /* point to block header */
old_size = sizeof(Header) * (bp->s.size - 1);
new_ptr = malloc(size);
if (new_ptr == NULL) {
return NULL;
}
if (old_size <= size) {
memcpy(new_ptr, ptr, old_size);
} else {
memcpy(new_ptr, ptr, size);
}
free(ptr);
return new_ptr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -