对齐的内存分配

时间:2010-08-03 17:26:37

标签: c malloc

我有以下任务:

  

在C中编写一个函数来分配内存块,并在这些条件下返回指向内存开头的指针:

     
      
  1. 块中的所有地址均可被32
  2. 整除   
  3. 至少分配了所需的字节数
  4.   
  5. 块中的每个单元格都初始化为零
  6.   
  7. 没有全局变体,最低复杂性
  8.         

    编写另一个也释放您分配的内存的函数。 (您知道上述内存是由您刚写的第一个函数分配的。)

这是一个调试临时解决方案:

“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);
}

现在我有几个问题:

  1. main()
  2. 中存在编译错误
  3. 我无法理解如何使用calloc代替malloc
  4. 如果我使用void*,是否可以选择将其转换为32个字节的块?

3 个答案:

答案 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