所有内存分配 [英] alligned memory allocation

查看:60
本文介绍了所有内存分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我已经得到了以下代码,它可以分配

对齐的内存(不确定对齐的内存分配是什么)。 />

void *

_align_calloc(size_t字节,无符号长对齐)

{

unsigned long ptr, buf;


ASSERT(对齐> 0);


ptr =(无符号长)calloc(bytes + alignment + sizeof(void *) ));

if(!ptr)

返回NULL;


buf =(ptr + alignment + sizeof(void *) ))& 〜(无符号长)(对齐 -

1);

*(无符号长*)(buf - sizeof(void *))= ptr;


#ifdef DEBUG

/ *标记未对齐区域* /

而(ptr< buf - sizeof(void *)){

*(unsigned long *)ptr = 0xcdcdcdcd;

ptr + = sizeof(unsigned long);

}

#endif


返回(无效*)buf;

}


有人可以解释一下这是什么代码在做什么?我有点困惑

内存被分配给非指针数据即无符号长

ptr?

kutty

Hi,
I ve got the following piece of code which does the role of allocating
aligned memory (not sure what aligned memory allocation is either).

void *
_align_calloc(size_t bytes, unsigned long alignment)
{
unsigned long ptr, buf;

ASSERT( alignment > 0 );

ptr = (unsigned long) calloc(bytes + alignment + sizeof(void *));
if (!ptr)
return NULL;

buf = (ptr + alignment + sizeof(void *)) & ~(unsigned long)(alignment -
1);
*(unsigned long *)(buf - sizeof(void *)) = ptr;

#ifdef DEBUG
/* mark the non-aligned area */
while ( ptr < buf - sizeof(void *) ) {
*(unsigned long *)ptr = 0xcdcdcdcd;
ptr += sizeof(unsigned long);
}
#endif

return (void *)buf;
}

Can somebody please explain what this code is doing? I m a little confused
with the memory being allocated to a non pointer data namely unsigned long
ptr ?
kutty

推荐答案

在文章< c2 *********** @ bigboote.WPI.EDU>,

" Kutty纳吉" <ク**** @ wpi.edu>写道:
In article <c2***********@bigboote.WPI.EDU>,
"Kutty Banerjee" <ku****@wpi.edu> wrote:

我有以下代码片段,它负责分配对齐的内存(不确定对齐的内存分配是什么) 。

void *
_align_calloc(size_t bytes,unsigned long alignment)
{
unsigned long ptr,buf;

ASSERT(对齐) > 0);

ptr =(unsigned long)calloc(bytes + alignment + sizeof(void *));
if(!ptr)
返回NULL;

buf =(ptr + alignment + sizeof(void *))& 〜(unsigned long)(对齐 -
1);
*(unsigned long *)(buf - sizeof(void *))= ptr;

#ifdef DEBUG
/ *标记未对齐区域* /
while(ptr< buf - sizeof(void *)){
*(unsigned long *)ptr = 0xcdcdcdcd;
ptr + = sizeof(unsigned long);
}


返回(void *)buf;
}

请有人解释一下这段代码在做什么?我有点困惑
将内存分配给非指针数据即unsigned long
ptr?
Hi,
I ve got the following piece of code which does the role of allocating
aligned memory (not sure what aligned memory allocation is either).

void *
_align_calloc(size_t bytes, unsigned long alignment)
{
unsigned long ptr, buf;

ASSERT( alignment > 0 );

ptr = (unsigned long) calloc(bytes + alignment + sizeof(void *));
if (!ptr)
return NULL;

buf = (ptr + alignment + sizeof(void *)) & ~(unsigned long)(alignment -
1);
*(unsigned long *)(buf - sizeof(void *)) = ptr;

#ifdef DEBUG
/* mark the non-aligned area */
while ( ptr < buf - sizeof(void *) ) {
*(unsigned long *)ptr = 0xcdcdcdcd;
ptr += sizeof(unsigned long);
}
#endif

return (void *)buf;
}

Can somebody please explain what this code is doing? I m a little confused
with the memory being allocated to a non pointer data namely unsigned long
ptr ?




这是一个无能为力的案例程序员试图以某种方式返回一个指针

。我会给你一个概述他试图做什么以及他错在哪里:


malloc和calloc返回指针正确对齐for _any_ C

类型。现在可能有理由为什么你想要一个指向

的指针与128字节的倍数对齐,例如,malloc就不会这样做。/ b
。 />

所以他所做的是分配一个更大的指针,让我们说一个指针

" char * p",在128字节对齐的情况下你会在0到127之间添加一些

值,使其在128个字节的倍数上对齐。但是

如果你这样做并返回了结果指针,那么你就不会以后可以释放内存:为了能够免费通话,你必须有原始指针

。所以你将原始指针存放在你返回的指针前面。


现在你的原作者做了一些非常愚蠢的事情。他在便携式C中做出了完全没有根据的假设,实际上在越来越多的实际使用的计算机上出现了错误的b $ b错误。难怪你

感到困惑:-(


首先,他认为对齐不仅大于零,而且还是

也是2的幂,并且至少和对齐要求一样大

的void *值。为什么他不在ASSERT中写这个?测试

是否x是2的幂:如果用二进制写x和x-1,那么如果x

是2的幂,则在x和x-中都不会设置任何位1.如果x非零并且不是2的幂,那么x的最高位也设置为x-1。所以

你可以写


ASSERT(对齐> = sizeof(void *)&&(align&(align-1))!= 0);


接下来,他假设您可以将无效*转换为无符号长并在无符号长上执行

指针算法.Bullshit。使用Athlon 64和

你可能是惊讶地发现void * = 64 bit,unsigned long = 32 bit,

并且将void *转换为unsigned long会产生一个整体很多垃圾。使用巨大来获取
16位DOS内存模型,并添加到unsigned long来执行指针算法会产生垃圾。试试Cray和天堂

知道你得到了什么。但实际上很容易以便携式方式做他想要的东西:


char * p = calloc(bytes + alignment + sizeof (void *));

char * q = p + sizeof(void *)+ alignment;

q - =((unsigned long)q)%alignment;


//如果你想让你的代码像原作者一样不可读,那么

//然后将最后一行更改为

// q - =((无符号长)q)& (对齐 - 1);


现在无论指针的长度和未签名的长度是多少都是无关紧要的。


他犯的下一个错误是你可以存储一个unsigned long,如果

你有空格*。错误。正如你有系统

sizeof(void *)> sizeof(unsigned long),你有系统的地方

反之亦然。购买一台新的Macintosh,你会得到一台机器,它使用64位整数和32位指针。所以他有这个指针buf,

减去四个字节= sizeof(void *),并存储一个8字节的无符号

长。恭喜。一旦使用内存,调用者就会覆盖该无符号长整数的最后四个字节

。当你的时候崩溃

稍后试着释放内存。


和这个人的代码玩得开心。期待最坏的情况。那些认为他们可以编程并且不是最糟糕的人。



It is a case of a clueless programmer trying to return a pointer that is
aligned in a certain way. I''ll give you an overview what he is trying to
do and where he gets it wrong:

malloc and calloc return pointers that are properly aligned for _any_ C
type. Now there might be reasons why you would want a pointer that is
aligned to multiples of 128 bytes, for example, and malloc won''t do
that.

So what he does is allocate a pointer that is bigger, lets say a pointer
"char* p", and in the case of 128 byte alignment you would add some
value from 0 to 127 to make it aligned on a multiple of 128 bytes. But
if you did just that and returned the result pointer, then you wouldn''t
be able to free the memory later: To be able to call free, you must have
the original pointer. So you store the original pointer just in front of
the pointer that you return.

Now your original author does a few remarkably stupid things. He makes
assumptions that are completely unwarranted in portable C and actually
wrong on more and more computers that are in actual use. No wonder you
are confused :-(

First, he assumes that "alignment" is not only greater than zero, but
also a power of two, AND at least as large as the alignment requirement
of a void* value. Why doesn''t he write this in the ASSERT? To test
whether x is a power of two: If you write x and x-1 in binary, then if x
is a power of two no bit will be set both in x and x-1. If x is nonzero
and not a power of two, then the highest bit of x is also set in x-1. So
you could write

ASSERT(align >= sizeof (void *) && (align & (align-1)) != 0);

Next, he assumes that you can cast a void* to unsigned long and perform
pointer arithmetic on the unsigned long. Bullshit. Take an Athlon 64 and
you may be surprised to see that void* = 64 bit, unsigned long = 32 bit,
and casting void* to unsigned long produces a whole lot of garbage. Take
16 bit DOS with "huge" memory model, and adding to an unsigned long to
do pointer arithmetic will produce garbage. Try it on a Cray and heaven
knows what you get. But in fact it is very easy to do what he wants in a
much more portable way:

char* p = calloc (bytes + alignment + sizeof (void *));
char* q = p + sizeof (void *) + alignment;
q -= ((unsigned long) q) % alignment;

// If you want your code unreadable like the original author,
// then change the last line to
// q -= ((unsigned long) q) & (alignment - 1);

Now it doesn''t matter what the relative sizes of pointers and unsigned
long are.

The next mistake that he makes is that you can store an unsigned long if
you have space for a void*. Bad mistake. Just as you have systems where
sizeof (void *) > sizeof (unsigned long), you have systems where it is
the other way round. Buy a new Macintosh and you will get a machine that
uses 64 bit integers and 32 bit pointers. So he has this pointer "buf",
subtracts four byte = sizeof (void *), and stores an eight byte unsigned
long. Congratulations. The last four bytes of that unsigned long will be
overwritten by the caller as soon as they use the memory. Crash when you
try to free the memory later on.

Have fun with this guy''s code. Expect the worst. People who think they
can program and can''t are the worst kind.


Christian Bau写道:
Christian Bau wrote:
Kutty Banerjee <ク**** @ wpi.edu>写道:
"Kutty Banerjee" <ku****@wpi.edu> wrote:
我得到了以下代码,它的作用是分配对齐的内存(不确定对齐的内存分配是什么)。 br />
void *
_align_calloc(size_t字节,无符号长对齐)
{
....剪切代码......
有人可以解释一下这是什么代码在做什么?我很难将内存分配给非指针数据,即unsigned long ptr?
这是一个无能的程序员试图返回指针的情况
以某种方式对齐。我会给你一个概述他正在尝试做什么以及他弄错了什么:
I ve got the following piece of code which does the role of
allocating aligned memory (not sure what aligned memory
allocation is either).

void *
_align_calloc(size_t bytes, unsigned long alignment)
{ .... snip code ...
Can somebody please explain what this code is doing? I m a
little confused with the memory being allocated to a non
pointer data namely unsigned long ptr ?
It is a case of a clueless programmer trying to return a pointer
that is aligned in a certain way. I''ll give you an overview what
he is trying to do and where he gets it wrong:



.... snip ...
有这个家伙的代码很有趣。期待最坏的情况。那些认为自己可以编程并且不是最差的人。


.... snip ...
Have fun with this guy''s code. Expect the worst. People who
think they can program and can''t are the worst kind.




代码显然不便携,而且显然也是打算

供系统使用(_align ...名称不在用户名中

空格)。这个问题根本不能与

可移植代码一起使用,因此唯一的要求是它可以使用原始实现以某种方式或其他方式工作。你的刻薄批评

可能是不值得的。


对于OP:特定系统的内部运作通常是很好的b
精彩,高度不规范。你不是希望根据语言来理解它们。


-

Chuck F(cb ** ****** @ yahoo.com)(cb********@worldnet.att.net)

可用于咨询/临时嵌入式和系统。

< http://cbfalconer.home.att.net>使用worldnet地址!



The code is obviously not portable, and is also obviously intended
for system use (the _align... name is not in the user name
space). This is a problem that is simply not soluble with
portable code, so the only requirement is that it work, somehow or
other, with the original implementation. Your caustic criticisms
are probably undeserved.

To the OP: The internal workings of a particular system are often
wierd and wonderful, and highly non-standard. You are not
expected to understand them on the basis of the language.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


文章< 40 *************** @ yahoo.com>,

CBFalconer< cb ******** @ yahoo.com>写道:
In article <40***************@yahoo.com>,
CBFalconer <cb********@yahoo.com> wrote:
Christian Bau写道:
Christian Bau wrote:
享受这个家伙的代码。期待最坏的情况。那些认为自己可以编程而且不是最差的人。
Have fun with this guy''s code. Expect the worst. People who
think they can program and can''t are the worst kind.



这些代码显然不便携,显然也适用于系统use(_align ... name不在用户名
空间中)。这是一个根本无法用于可移植代码的问题,因此唯一的要求是它在原始实现中以某种方式或其他方式工作。你的刻薄批评可能是不应该的。



The code is obviously not portable, and is also obviously intended
for system use (the _align... name is not in the user name
space). This is a problem that is simply not soluble with
portable code, so the only requirement is that it work, somehow or
other, with the original implementation. Your caustic criticisms
are probably undeserved.




重点是这个代码没有任何正当理由是不可移植的。并且

假设unsigned long和void *具有相同的大小,今天只是

完全是愚蠢的。不是它在除死亡站之外的任何地方都有用

9000"有点愚蠢,但是我买了这台全新的电脑和我的

代码在整个地方崩溃了有点愚蠢。



The point is that this code is unportable without any good reason. And
assuming that unsigned long and void* have the same size, today, is just
utterly stupid. Not the "it works everywhere except on the DeathStation
9000" kind of stupid, but the "I bought this brand new computer and my
code crashes all over the place" kind of stupid.


这篇关于所有内存分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆