又一个免费()问题。 [英] Yet another free() question.

查看:60
本文介绍了又一个免费()问题。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于使用free()的问题,基于我需要的一些代码

来破译:


{

struct A {< A fields>};

struct B {< A fields +< Bfields>};


typedef struct A Aobj;

typedef struct B Bobj;


Aobj * ptrToA =(struct A *)calloc(1,sizeof(struct B));


免费(ptrToA);

}


这会释放size sizeof(struct B)的整个内存块,还是

只是一个从大小为sizeof(struct A)的ptrToA开始的块?我强烈建议阅读的帖子强烈建议,这可能会释放calloc()产生的整个块,但在这些帖子中似乎是

sizeof(Aobj)== N * sizeof(Bobj),即分配块的大小是

指针的解除引用类型的整数倍

分配的块'的无效指针已被强制转换(不知道如何表达

)。当在堆上分配对象的单个实例

或相同对象的数组时就是这种情况。只想要

确保上面做的是安全的(假设类型解释
其他地方分配块的
是正确的。)


谢谢您的时间。

解决方案

la ******* @ gmail.com 写道:


我对free()的使用有疑问基于我需要的一些代码

来破译:


{

struct A {< A fields>};

struct B {< A fields +< Bfields>};


typedef struct A Aobj;

typedef struct B Bobj;


Aobj * ptrToA =(struct A *)calloc(1,sizeof(struct B));


free(ptrToA);

}


这将释放大小sizeof(struct B)的整个内存块,或者

只释放一个从ptrToA开始的块size sizeof(struct A)?帖子我

强烈建议这可能会释放由calloc()生成的整个块,



是的,这就是它的作用。值得注意的是,如果

calloc成功,那么它分配的内存是*在
最小*与sizeof(struct B)一样大,它没有是

正好是sizeof(结构B)。


但是在那些帖子中似乎是

sizeof(Aobj )== N * sizeof(Bobj),即分配块的大小是

指针的解除引用类型的整数倍,

分配的块'无效的指针被投下(不知道怎么表达这个好的b $ b)。



我将通过取消引用的指针类型来猜测你

表示指针指向的对象类型。无论如何

是否sizeof(Aobj)== N * sizeof(Bobj)持有或是否

sizeof(* Aobj)== N * sizeof(* Bobj)持有无关紧要,

free()将释放由calloc分配的所有内存(如果有的话)



在堆上分配单个实例

的对象或相同对象的数组时会出现这种情况。



由于堆的存在取决于实现

,因此最好不要使用该术语。如果你的意思是通过malloc系列功能获得了内存,那么那就是你应该说的那个




拥有说,你指的是哪种情况?

公式sizeof(Aobj)== N * sizeof(Bobj)你提到了

2种不同的对象类型。


只想

确保上面所做的是安全的(假设类型解释
其他地方分配块的
是正确的。)



我不知道

分配块的类型解释是什么是。 mallocing内存和释放

它马上是安全的,但显然毫无意义。是否

您的代码是否安全取决于

calloc()和free()之间发生的事情。


la*******@gmail.com 写道:


我有一个关于使用free()的问题,基于我需要的一些代码

来破译:


{

struct A {< A fields>};

struct B {< A fields +< Bfields>};


typedef struct A Aobj;

typedef struct B Bobj;


Aobj * ptrToA =(struct A *)calloc(1,sizeof(结构B));


免费(ptrToA);

}


这将释放整个内存块sizeof(struct B),或

只是一个从size sizeof(struct A)的ptrToA开始的块?我强烈建议阅读的帖子强烈建议,这可能会释放calloc()产生的整个块,但在这些帖子中似乎是

sizeof(Aobj)== N * sizeof(Bobj),即分配块的大小是

指针的解除引用类型的整数倍

分配的块'的无效指针已被强制转换(不知道如何表达

)。当在堆上分配对象的单个实例

或相同对象的数组时就是这种情况。只想要

确保上面做的是安全的(假设类型解释
其他地方分配块的
是正确的。)



是的。


malloc / calloc / realloc / free子系统没有,也不能,

跟踪你做了什么使用新分配的指针后,

将其值返回给您。假设sizeof(struct A)== 10,

和sizeof(struct b)== 20.在你的代码中,calloc(如果成功)

只返回一个void *指向新分配的20个字节的内存;

它不知道值20被计算为sizeof(struct B),

或者你转换后的那个结果从void *到struct A *。


当你调用free(PtrToA)时,free()只能看到一个类型为

void *的参数,碰巧与

calloc()返回的值相同,所以它释放了20个字节。


sizeof,强制转换和赋值

calloc()和free()是完全不可见的,并且不会影响他们的行为。至于

calloc()和free(),你的代码相当于:


void * ptr = calloc(1,20) ;

免费(ptr);


顺便提一下,标准并不能*保证最初的

字段你的结构A和结构B将一致地布局,

除非你碰巧宣布两种类型的联合,尽管它很难想象一个它们不匹配的实现。

你可能会考虑使struct B的第一个成员类型为
struct A,而不是明确地复制所有字段;这个

也可以避免因编写

两次相同的成员声明序列而引入的任何错误,


-

Keith Thompson(The_Other_Keith) ks***@mib.org < http:// www。 ghoti.net/~kst>

圣地亚哥超级计算机中心< *< http://users.sdsc.edu/~kst>

我们必须做点什么。这是事情。因此,我们必须这样做。


Keith Thompson写道:


顺便提一下,标准不是*相当*保证结构A和结构B的初始

字段将一致地布局,

,除非您碰巧声明了两种类型的并集,尽管很难想象一个他们不会匹配的实现。

你可能会考虑让struct B的第一个成员属于

struct A,而不是明确地复制所有字段;这个

也可以避免因编写

相同的成员声明序列两次而引入的任何错误,



因为calloc()返回的内容保证

适当地分配给任何类型我不知道什么

即使在理论上也可能出错。除非你说

,sizeof(struct A)可能大于sizeof(struct B)。


I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof(struct B));

free(ptrToA);
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)? The posts I
have read strongly suggest this will, as probably intended, free the
entire block produced by calloc(), but in those posts it seems
sizeof(Aobj) == N*sizeof(Bobj), i.e. the size of the allocated block is
an integer multiple of the dereferenced type of the pointer to which
the allocated block''s void pointer is cast (Don''t know how to express
this well). Such would be the case when allocating a single instance
of an object or an array of the same objects on the heap. Just want to
make sure what is done above is safe (assuming the type interpretation
of the allocated block elsewhere is correct.)

Thank you for your time.

解决方案

la*******@gmail.com wrote:

I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof(struct B));

free(ptrToA);
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)? The posts I
have read strongly suggest this will, as probably intended, free the
entire block produced by calloc(),

Yes , that''s what it will do. It is worth noting that if the
calloc succeeded then it allocated memory which is *at
least* as large as sizeof(struct B) , it doesn''t have to be
exactly sizeof(struct B).

but in those posts it seems
sizeof(Aobj) == N*sizeof(Bobj), i.e. the size of the allocated block is
an integer multiple of the dereferenced type of the pointer to which
the allocated block''s void pointer is cast (Don''t know how to express
this well).

I will guess that by "dereferenced type of the pointer" you
mean the type of object the pointer points to. In any case
whether sizeof(Aobj) == N*sizeof(Bobj) holds or whether
sizeof(*Aobj) == N*sizeof(*Bobj) holds is irrelevant , the
free() will free all the memory (if any) which was allocated
by calloc.

Such would be the case when allocating a single instance
of an object or an array of the same objects on the heap.

Since the presence of a heap is up to an implementation
it''s best not use the term. If you mean memory obtained
through the malloc family of functions then that''s what
you should say.

Having said that , which case are you referring to ? The
formula sizeof(Aobj) == N*sizeof(Bobj) you gave mentions
2 different object types.

Just want to
make sure what is done above is safe (assuming the type interpretation
of the allocated block elsewhere is correct.)

I don''t know what "the type interpretation of the
allocated block" is. mallocing memory and freeing
it right away is safe but obviously pointless. Whether
your code is safe depends on what''s happening between
the calloc() and the free().


la*******@gmail.com writes:

I have a question regarding the use of free() based on some code I need
to decipher:

{
struct A {<A fields>};
struct B {<A fields+ <Bfields>};

typedef struct A Aobj;
typedef struct B Bobj;

Aobj *ptrToA = (struct A*) calloc(1,sizeof(struct B));

free(ptrToA);
}

Will this free the entire memory block of size sizeof(struct B), or
only a block starting at ptrToA of size sizeof(struct A)? The posts I
have read strongly suggest this will, as probably intended, free the
entire block produced by calloc(), but in those posts it seems
sizeof(Aobj) == N*sizeof(Bobj), i.e. the size of the allocated block is
an integer multiple of the dereferenced type of the pointer to which
the allocated block''s void pointer is cast (Don''t know how to express
this well). Such would be the case when allocating a single instance
of an object or an array of the same objects on the heap. Just want to
make sure what is done above is safe (assuming the type interpretation
of the allocated block elsewhere is correct.)

Yes.

The malloc/calloc/realloc/free subsystem does not, and cannot,
keep track of what you do with the newly allocated pointer after
its value is returned to you. Suppose sizeof(struct A) == 10,
and sizeof(struct b) == 20. In your code, calloc (if successful)
simply returns a void* pointer to 20 bytes of newly allocated memory;
it has no idea that the value 20 was computed as "sizeof(struct B),
or that you then converted the result from void* to struct A*.

When you call free(PtrToA), free() sees only an argument of type
void*, which happens to have the same value as what was returned by
calloc(), so it frees 20 bytes.

The sizeof, the cast, and the assignment are entirely invisible to
calloc() and free(), and cannot affect their behavior. So as far as
calloc() and free() are concerned, your code is equivalent to:

void *ptr = calloc(1, 20);
free(ptr);

Incidentally, the standard doesn''t *quite* guarantee that the initial
fields of your struct A and struct B will be laid out consistently,
unless you happen to declare a union of the two types, though it''s
difficult to imagine an implementation in which they wouldn''t match.
You might consider making the first member of struct B be of type
struct A, rather than duplicating all the fields explicitly; this
would also avoid any errors that might be introduced by writing the
same sequence of member declarations twice,

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.


Keith Thompson wrote:

Incidentally, the standard doesn''t *quite* guarantee that the initial
fields of your struct A and struct B will be laid out consistently,
unless you happen to declare a union of the two types, though it''s
difficult to imagine an implementation in which they wouldn''t match.
You might consider making the first member of struct B be of type
struct A, rather than duplicating all the fields explicitly; this
would also avoid any errors that might be introduced by writing the
same sequence of member declarations twice,

Since what is returned by calloc() is guaranteed to
be properly alligned for any type I don''t see what
might go wrong even in theory. Unless you''re saying
that sizeof(struct A) may be larger than sizeof(struct B).


这篇关于又一个免费()问题。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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