【发布时间】:2021-03-10 18:05:38
【问题描述】:
我遇到了以下代码here。
/* Allocate aligned memory in a portable way.
*
* Memory allocated with aligned alloc *MUST* be freed using aligned_free.
*
* @param alignment The number of bytes to which memory must be aligned. This
* value *must* be <= 255.
* @param bytes The number of bytes to allocate.
* @param zero If true, the returned memory will be zeroed. If false, the
* contents of the returned memory are undefined.
* @returns A pointer to `size` bytes of memory, aligned to an `alignment`-byte
* boundary.
*/
void *aligned_alloc(size_t alignment, size_t size, bool zero) {
size_t request_size = size + alignment;
char* buf = (char*)(zero ? calloc(1, request_size) : malloc(request_size));
size_t remainder = ((size_t)buf) % alignment;
size_t offset = alignment - remainder;
char* ret = buf + (unsigned char)offset;
// store how many extra bytes we allocated in the byte just before the
// pointer we return
*(unsigned char*)(ret - 1) = offset;
return (void*)ret;
}
/* Free memory allocated with aligned_alloc */
void aligned_free(void* aligned_ptr) {
int offset = *(((char*)aligned_ptr) - 1);
free(((char*)aligned_ptr) - offset);
}
解释:
char *ret = buf + (unsigned char)offset;在这里,我们设置了一个新指针,它比 buf 的基地址提前了偏移字节。例如我们想在一个 16 位对齐的内存中分配 68 个字节,它看起来像这样:
requested_size = 68+16 = 84假设 buf 的基地址是buf = 0x112223341然后remainder = sizeof(buf)%16 = (84%16) = 4offset = 16 - 4 = 12 (i.e. 0x0C)ret = &buf + offset = 0x11223341+0x0C = 0x1122334D
问题:
以下行是做什么的? 我在理解这种语法和实现结果时遇到了一些麻烦。
*(unsigned char*)(ret - 1) = offset
当我们返回 ret 时,那些被分配但绝不是 ret 基地址的一部分的额外字节会发生什么?也就是说,如果我们分配了 16 个额外的字节,但只需要 12 个字节进行对齐,那么剩下的字节会发生什么?
=======更新问题中的代码=======
感谢@ThomasMailund 和他的见解,我认为我可以安全地修改上述代码以简化一些类型转换,如下所示:
/* Allocate aligned memory in a portable way.
*
* Memory allocated with aligned alloc *MUST* be freed using aligned_free.
*
* @param alignment The number of bytes to which memory must be aligned. This
* value *must* be <= 255.
* @param bytes The number of bytes to allocate.
* @param zero If true, the returned memory will be zeroed. If false, the
* contents of the returned memory are undefined.
* @returns A pointer to `size` bytes of memory, aligned to an `alignment`-byte
* boundary.
*/
void *aligned_alloc(size_t alignment, size_t size, bool zero) {
size_t request_size = size + alignment;
unsigned char *buf = zero ? calloc(1, request_size) : malloc(request_size);
size_t remainder = ((size_t)buf) % alignment;
size_t offset = alignment - remainder;
unsigned char *ret = buf + (unsigned char)offset;
// store how many extra bytes we allocated in the byte just before the
// pointer we return
*(ret - 1) = offset;
return ret;
}
/* Free memory allocated with aligned_alloc */
void aligned_free(void* aligned_ptr) {
int offset = *(((char*)aligned_ptr) - 1);
free(((char*)aligned_ptr) - offset);
}
【问题讨论】:
标签: c pointers memory dynamic-memory-allocation memory-alignment