-4

我正在实现一个用户级线程库作为分配。内存分配是在原始代码本身中完成的。但似乎很难理解代码中发生了什么。谁能帮我解释一下。

void * malloc_stack() 
{
  /* allocate something aligned at 16
   */
   void *ptr = malloc(STACK_SIZE + 16);
   if (!ptr) return NULL;
   ptr = (void *)(((int)ptr & (-1 << 4)) + 0x10);
   return ptr;
}

编辑:因为堆栈向下增长,分配给 ptr 的地址是什么?它是堆栈的底部还是堆栈的顶部?

假设base在较高的内存地址,top在较低的内存地址(因为向下增长)

4

3 回答 3

0

这看起来像 的实现aligned_malloc,当您有一个处理器(或协处理器,或支持 DMA 的设备),其中一些或所有指令(操作)只能在对齐的内存上工作时,这很有用。除了在未对齐的内存上完全失败的指令外,对齐可能会影响原子性。

它与堆栈无关。就其本质而言,动态分配不能来自堆栈,因为堆栈上的分配不会在返回到调用函数时继续存在,但动态分配必须在匹配的释放调用之前继续存在。

(换一种说法:根据定义,堆栈是后进先出。动态分配不是 LIFO,但可以适应生命周期的任意顺序。)

于 2013-03-31T05:50:55.780 回答
0

我正在实现一个用户级线程库作为分配。内存分配是在原始代码本身中完成的。但似乎很难理解代码中发生了什么。谁能帮我解释一下。

当然。C 标准说:E1 << E2 的结果是 E1 左移 E2 位;空出的位用零填充。如果 E1 具有无符号类型,{无关遗漏}。如果 E1 具有带符号类型和非负值,并且 E1 × 2E2 在结果类型中是可表示的,那么这就是结果值;否则,行为未定义。

因此,-1 << 4是未定义的行为。以下是 C 标准对未定义行为的解释:行为,在使用不可移植或错误程序构造或错误数据时,本国际标准对此没有任何要求

因此,没有此代码的要求。它可以做任何事情,或者什么都不做,而且它不需要任何理由或逻辑来这样做。据我们所知,它可以依靠仙尘传感器正常运行……

编辑:因为堆栈向下增长,分配给 ptr 的地址是什么?...

什么栈?这不是一个地址,因为它不能保证指向一个对象。将其视为存在也是未定义的行为:如果左值在评估时未指定对象,则该行为是未定义的。

下一个问题:

...它是堆栈的底部还是堆栈的顶部?

它可能是,也不是,任何东西或一切(包括高度传染性的仙女癌症尘埃)。未定义的行为...

假设base在较高的内存地址,top在较低的内存地址(因为向下增长)

......会很愚蠢。未定义的行为...

此代码可能在您的系统上以您的配置正常运行,但考虑到不同的操作系统、硬件、C 标准库或编译器可能会出现故障。C 的设计并非只与您的系统兼容,而是与多种系统兼容;C代码不应该这样写!C 语言的设计目的是让程序可以移植或独立于操作系统、硬件、C 标准库和编译器实现编写!你在看哪本书?

于 2013-03-31T06:25:03.750 回答
-1

因此,如果我正确理解了这个问题,您需要帮助理解这段代码

我假设你理解函数的前两行和最后一行,所以只剩下

ptr = (void *)(((int)ptr & (-1 << 4)) + 0x10);

首先我们应该看看(-1 << 4)。既然你投了ptr我相信假设 -1 也将被视为一个 int 并将成为值是安全的0xFFFFFFFF(这将假设你的系统的 int 有 4 个字节或 32 位,我认为这是一个非常普遍的东西现在。接下来,既然有一个转变,我们应该看看这个的二进制表示,所以-1 = 0xFFFFFFFF = 0b11111111111111111111111111111111如此移位 4 (-1 << 4) = 0b11111111111111111111111111110000 = 0xFFFFFFF0...。

接下来ptr是与这个值相加,这意味着ptr将被强制以 结束0000。请注意,使用这种格式转换任何类型的数字时,它都可以被 16 整除,从而ptr16. 然后它添加0x10以强制地址位于分配的区域内。

希望这可以帮助!

编辑:因为堆栈向下增长,分配给 ptr 的地址是什么?它是堆栈的底部还是堆栈的顶部?

假设base在较高的内存地址,top在较低的内存地址(因为向下增长)

正如评论中的人指出的那样:这种行为非常不确定。如果这是为了家庭作业,我怀疑是这样,我建议您验证这是您的机器的行为(并且可能是正在评分的机器)。否则要修复它,您可以简单地替换-10xFFFFFFFF,然后我相信问题应该得到解决(我再次没有咨询 c 标准,这只是从经验的角度来看)。请注意,用我解释的内容替换-1应该0xFFFFFFFFu仍然有意义。

于 2013-03-31T05:56:00.493 回答