我有以下任务:
在C中编写一个函数来分配内存块,并在这些条件下返回指向内存开头的指针:
- 块中的所有地址均可被32
整除- 至少分配了所需的字节数
- 块中的每个单元格都初始化为零
- 没有全局变体,最低复杂性
醇>编写另一个也释放您分配的内存的函数。 (您知道上述内存是由您刚写的第一个函数分配的。)
这是一个调试临时解决方案:
“aligned_malloc.h”:
#ifndef __ALIGNED_MALLOC_H__
#define __ALIGNED_MALLOC_H__
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define ALIGNMENT 16
#if ALIGNMENT > 255
#error "This 'void *aligned_malloc(size_t size)' function can only handle alignment < 256"
#endif
#if ALIGNMENT < 0
#error "This 'void *aligned_malloc(size_t size)' function can only handle a non negative alignment"
#endif
void* aligned_malloc(size_t size);
void aligned_free(void *aligned_p);
#endif /* __ALIGNED_MALLOC_H__ */
“alligned_malloc.c”:
#include "aligned_malloc.h"
#undef DEBUG
#define DEBUG 1
int main()
{
size_t size = 0;
void *memblk = NULL;
do while (size > 0 )
{
printf("\nPlease enter in bytes the memory block size you want to allocate (0 to exit): ");
scanf("%d", &size);
memblk = aligned_malloc(size);
#ifdef DEBUG
printf("%s[%d]: memblk = 0x%x\n", __FUNCTION__, __LINE__, memblk);
#endif /* DEBUG */
}
if (memblk != NULL)
aligned_free(memblk);
return 0;
}
void *aligned_malloc(size_t size)
{
int i = 0;
void* memblk = malloc(size + ALIGNMENT);
printf ("\n%ld",(long)memblk);
//offset is the start address of memblk (long=8digit) modulo the ALIGNMENT
unsigned char offset = ALIGNMENT - ((long)memblk % ALIGNMENT);
printf ("\n%d",offset);
if (memblk == NULL)
return NULL;
/* O/W: */
#ifdef DEBUG
printf("%s[%d]: memblk = 0x%x\n", __FUNCTION__, __LINE__, memblk);
#endif /* DEBUG */
for (i = offset; i < size + ALIGNMENT; i++)
{
printf("%02d: %08d\n", i, memblk+i);
memblk[i] = 0;
}
*(memblk + offset - 1) = offset;
return (void*)(memblk + offset);
}
void aligned_free(void *aligned_p)
{
unsigned char offset = (unsigned char)(*((unsigned char *)aligned_p-1));
#ifdef DEBUG
printf("%s[%d]: offset = %d\n", __FUNCTION__, __LINE__, offset);
printf("%s[%d]: aligned_p-1 = 0x%x\n", __FUNCTION__, __LINE__, (unsigned char *)aligned_p-1);
printf("%s[%d]: aligned_p-offset = 0x%x\n", __FUNCTION__, __LINE__, aligned_p-offset);
#endif /* DEBUG */
free(aligned_p-offset);
}
现在我有几个问题:
main()
calloc
代替malloc
void*
,是否可以选择将其转换为32个字节的块?答案 0 :(得分:2)
您的代码正在做正确的事情:您正在计算在对齐的块之前要跳过多少字节,并在块开始之前记录字节中的数字。你有几个基本问题:
在C中你有一个do { ... } while(cond)
循环或一个while(cond) { ... }
循环,但你已经把这两个混淆了。你的语法不合法,看起来你只想要一个while循环。
你无法对void *指针进行指针运算,因为void没有大小。将您的新地址计算为long:((long)memblk+offset)
或作为指向单个字节大小的类型的指针(如char)。目前,添加是一个void *类型,给出了其他编译错误。
猜测你从代码中看到的编译错误是相当棘手的 - 将来如果你发布你看到的错误会更容易。
答案 1 :(得分:0)
你的do-while语法错误。应该是:
do
{
/* stuff to do */
} while(xxx);
关于calloc
,它需要(1)你要分配的“东西”的数量,以及(2)每件东西的大小。它返回一个归零的内存块,其中包含空格以容纳这么多东西。
我不明白有关将void *转换为32位块的信息。
答案 2 :(得分:0)
我的错误SoRRy: - |
只有返回的地址应该被32分,即100B - &gt; 64 ... 164 ALIGNMENT应该在头文件中设置为32,这是一个工作代码:
#include "aligned_malloc.h"
#undef DEBUG
#define DEBUG 1
int main(void)
{
size_t size = 0;
void *res = NULL;
printf("\nPlease enter size: ");
scanf("%d", &size);
while (size > 0) {
res = aligned_malloc(size);
#ifdef DEBUG
printf("%s[%d]: res = 0x%x\n", __FUNCTION__, __LINE__, res);
#endif /* DEBUG */
if (res != NULL)
aligned_free(res);
printf("\nPlease enter size again (enter 0 to quit): ");
scanf("%d", &size);
}
return 0;
}
void *aligned_malloc(size_t size)
{
int i = 0;
long *res = malloc(size + ALIGNMENT);
unsigned char offset = ALIGNMENT - ((long)res % ALIGNMENT);
if (res == NULL)
return NULL;
/* O/W: */
#ifdef DEBUG
printf("%s[%d]: res = 0x%x\n", __FUNCTION__, __LINE__, res);
#endif /* DEBUG */
for (i = offset; i < size + ALIGNMENT; i++) {
printf("%02d: %08d\n", i, res+i);
res[i] = 0;
}
*(res + offset - 1) = offset;
return (void*)(res + offset + 1);
}
void aligned_free(void *aligned_p)
{
unsigned char offset = (unsigned char)(*((unsigned char *)aligned_p-1));
#ifdef DEBUG
printf("%s[%d]: offset = %d\n", __FUNCTION__, __LINE__, offset);
printf("%s[%d]: aligned_p-1 = 0x%x\n", __FUNCTION__, __LINE__, (unsigned char *)aligned_p-1);
printf("%s[%d]: aligned_p-offset = 0x%x\n", __FUNCTION__, __LINE__, aligned_p-offset);
#endif /* DEBUG */
free(aligned_p-offset);
}
PS我真的不知道是否有可能获得32B块... 日Thnx