面试里会遇到让自己编写一个内存管理函数
1. memset
将指定的内存区域的每个字节设置为指定的值
函数原型:
void *memset(void *s, int c, size_t n);
- 参数:
s
: 指向要填充的内存块的指针。c
: 要设置的值(会被转换为无符号字符)。n
: 要设置的字节数。
- 用途: 常用于初始化数组或清空内存,例如将一个数组的所有元素设置为 0。
- 示例:
int arr[5];
memset(arr, 0, sizeof(arr)); // 将 arr 的所有元素设置为 0
自己编写:
void *my_memset(void *s, int c, size_t n) { unsigned char *p = s; // 将 void* 转换为 unsigned char* while (n--) { *p++ = (unsigned char)c; // 设置每个字节 } return s; // 返回原始指针
}
2. memcpy
用于复制源内存到目标内存。
- 函数原型:
void *memcpy(void *dest, const void *src, size_t n);
- 参数:
dest
: 指向目标内存区域的指针(将数据复制到这里)。src
: 指向源内存区域的指针(从这里复制数据)。n
: 要复制的字节数。
示例
int src[5] = {1, 2, 3, 4, 5};
int dest[5];
memcpy(dest, src, sizeof(src)); // 将 src 的内容复制到 dest
自己编写
void *my_memcpy(void *dest, const void *src, size_t n) { unsigned char *d = dest; // 目标指针 const unsigned char *s = src; // 源指针 while (n--) { *d++ = *s++; // 逐个字节复制 } return dest; // 返回目标指针
}
3. memmove
用于从一个内存区域复制数据到另一个内存区域,支持内存重叠。
函数原型:
int memcmp(const void *s1, const void *s2, size_t n);
自己编写
void *my_memmove(void *dest, const void *src, size_t n) { unsigned char *d = dest; const unsigned char *s = src; if (d < s) { // 正常复制 while (n--) { *d++ = *s++; } } else { // 从后向前复制 d += n; s += n; while (n--) { *(--d) = *(--s); } } return dest;
}
4. memcmp
比较两个内存块的内容。
int my_memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *p1 = s1; const unsigned char *p2 = s2; while (n--) { if (*p1 != *p2) { return *p1 - *p2; // 返回两个不同字节的差 } p1++; p2++; } return 0; // 相等
}
5. malloc
会请求操作系统分配一定量的内存。一般实现比较复杂,这里给出一个非常简化的版本。
void *my_malloc(size_t size) { void *ptr = sbrk(size); // 使用 sbrk 请求内存(仅用于示例,真实情况下更复杂) return (ptr == (void *)-1) ? NULL : ptr; // 错误处理
}
6. free
用于释放先前分配的内存。
void my_free(void *ptr) { // 这里通常需要将指针返回内存管理系统 // 真实情况下,这需要维护一个内存块的链表或其他结构
}
7. realloc
是调整动态内存块的大小,通常会先调用 malloc
和 memcpy
。
void *my_realloc(void *ptr, size_t size) { if (ptr == NULL) { return my_malloc(size); // 如果原指针为 NULL,分配新内存 } // 获取原内存块的大小(具体实现中可能需要额外存储大小) size_t old_size = /* ... */; void *new_ptr = my_malloc(size); if (new_ptr) { my_memcpy(new_ptr, ptr, old_size < size ? old_size : size); my_free(ptr); // 释放旧内存 } return new_ptr; // 返回新指针
}