【问题标题】:Memory allocation and free内存分配和空闲
【发布时间】:2011-07-13 11:59:56
【问题描述】:

是否可以通过任何 Windows API 分配 7 个字节的内存并仅释放前 3 个字节以形成一个 4 字节块。

【问题讨论】:

  • 有什么用?如果你能更好地描述你想要实现的目标,你会得到有意义的答案......
  • 你为什么要这样做?为什么不先分配 4 个字节?
  • 做一个 realloc 并让实现担心它应该如何获得你需要的 4 个字节。如果您需要确定(因为您需要使用相同的指针)自己实现内存分配器。 PS:我不认为 Windows 提供任何机制来保存指针。你总是可以为你的 7 字节内存块使用一个长度参数,告诉你“允许”使用多少内存。
  • AFAIR Windows 本身管理 4K 块的内存。较低的值由 c 编译器的内存管理器管理。
  • 我需要分配的内存地址是 4 的倍数。我的地址应该是 400、404、408、40c 等,因此分配 7 并在其中找到 4 的倍数。

标签: c windows winapi memory memory-leaks


【解决方案1】:

没有。 Windows 堆分配 API 需要返回一个自然对齐的值(换句话说,块地址 % sizeof(void *) == 0)。对于 32 位处理器,这意味着每个分配都是 4 字节对齐的。如果有办法做你想做的事,新重新分配的块将在 3 字节边界上对齐(最初的 7 字节块将在 4 字节边界上对齐,添加 3 个字节会创建一个 3 字节对齐的指针。

正如其他人所建议的那样,将内存复制下来可以让您最接近您的要求。但这会带来一些性能成本。

【讨论】:

    【解决方案2】:

    您可以使用memmove() 将最后四个字节移动到分配块的开头,然后使用realloc() 将其缩小到四个字节。

    但是你为什么会想要呢?你总是可以有另一个指向分配内存的最后四个字节的指针,如下所示:

    typedef unsigned char uint8;
    
    uint8* psevenbytes = (uint8*)malloc(sizeof(uint8) * 7);
    
    if (psevenbytes != NULL)
    {
        uint8* pfourbytes = psevenbytes + 3;
    
        // ... do stuff
    
       free(psevenbytes);
       psevenbytes = NULL;
    }
    

    或者您可以使用struct

    【讨论】:

    • 如果我有另一个指针指向第 4 个字节并通过程序传递,我不确定我现在可以释放前 3 个字节作为指向第 4 个字节的指针。你能确认一下吗
    • @Beetle:没错,在该代码中,您必须使用psevenbytes 指针free 整个块。如果你想释放它的一部分,你必须使用memmove/realloc 讨论 - 但你为什么需要这样做??
    • 我需要分配的内存地址为 4 的倍数。我的地址应该是 400、404,408,40c 等,因此分配 7 并在其中找到 4 的倍数。还有比这更好的方法吗?
    • @Beetles:这是一个非常不寻常的要求!有什么特别的原因吗?在 32 位系统上,它可能会在 4 字节边界上对齐。在嵌入式系统上,您通常可以直接指定特定变量的地址。我建议您发布一个更一般的问题,询问您如何强制在四字节边界上分配内存,看看会出现什么答案。
    【解决方案3】:

    没有。

    但是您可以很好地使用 memmove 和 realloc 来减少使用的内存量:

    memmove(ptr, ptr + 3, 4);
    ptr = realloc(ptr, 4)
    

    但这很可能比将内存保持在初始大小要慢。

    【讨论】:

      猜你喜欢
      • 2014-11-24
      • 2018-10-09
      • 2022-01-19
      • 2015-03-21
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 2020-02-03
      • 2014-12-13
      相关资源
      最近更新 更多