微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用一个指向不同类型的指针进行免费调用?

如何解决用一个指向不同类型的指针进行免费调用?

如果我释放从一个指针转换为不同类型的指针,我认为它将导致内存泄漏;但是,我找不到确切的答案。

示例:

typedef struct ExampleStruct_s
{
    uint32_t a;
    uint32_t b;
    uint32_t c;
} ExampleStruct_t;

void main(void)
{
    ExampleStruct_t *p_struct = (ExampleStruct_t*)malloc(sizeof(ExampleStruct_t));
    uint32_t *p_uint32 = (uint32_t*) p_struct;
    free(p_uint32);
}

解决方法

根据C 2018 7.22.3.4,malloc返回void *。根据7.22.3.3,free的参数是void *,根据6.5.2.2,其参数将转换为void * 7.因此,free的参数永远不会与原始指向分配空间的指针不同的类型;它以void *开始和结束。

只有值不同才会有问题。指针转换的规则在6.3.2.3中。实际上,只要指针针对引用的类型正确对齐,它们就允许通过指针转换为不同的对象类型。根据7.22.3 1,malloc返回的值适用于任何 fundamental 对齐方式,包括所有基本,枚举和指针类型以及所有指向数组,结构或联合的指针其元素或成员具有基本对齐要求以及为标准库定义的所有完整对象类型。因此,只要您不将指针从malloc转换为具有比基本对齐要求更高的实现定义的扩展类型,或者不转换为使用_Alignas指定更大对齐方式的类型,转换将有效地保留从malloc返回的指针的原始值。

,

从对malloc的调用返回的值是void*指针(它是指向 unspecified 类型的指针)-在对的调用中传递的参数也是如此free。 (另请参见:Do I cast the result of malloc?

因此,只要您实际上没有更改指针的(即它包含的地址),那么代码中的内存泄漏就不会有问题。

,

这里主要关注的是从ExampleStruct_t *uint32_t *的转换。如果指针未正确对齐,将发生Undefined behavior。但是,由于指针值是从malloc返回的,因此它对于任何类型都正确对齐,因此应该没问题。

鉴于此,main第二行中的转换是安全的。因此,将指针传递到free(从malloc返回)将正确释放内存。

C standard中的相关引号:

6.3.2.3p1:

指向void的指针可以转换为任意指针 对象类型。指向任何对象类型的指针都可以转换为 指向void并再次返回的指针;结果应相等 指向原始指针

6.3.2.3p7:

指向对象类型的指针可能会转换为指向对象的指针 不同的对象类型。如果结果指针不正确 对于引用的类型对齐,则行为未定义。
否则,当再次转换回时,结果应进行比较 等于原始指针。当指向对象的指针是 转换为指向字符类型的指针,结果指向 对象的最低寻址字节。的连续增量 结果,根据对象的大小,产生指向其余对象的指针 对象的字节数。

7.22.3p1:

...如果分配成功,则返回的指针是适当的 对齐,以便可以将其分配给任何类型的对象的指针 具有基本对齐要求,然后用于访问此类 分配空间中的一个对象或此类对象的数组(直到 该空间已明确释放)...

,

此:

int main(void)
{
    ExampleStruct_t *p_struct = (ExampleStruct_t*)malloc(sizeof(ExampleStruct_t));
    uint32_t *p_uint32 = (uint32_t*) p_struct;
    free(p_uint32);
}

由于malloc()返回的指针的类型为void *,因此非常有效,因此可以保留正确的对齐方式。 (即使在转换为不同类型的指针之后。)此外,由于p_uint32的地址将与p_struct的地址完全相同,因此在调用{{时不会发生内存泄漏。 1}}。

唯一的建议是remove the castuse sizeof the object being allocated,not its type

free()

...并使用 ExampleStruct_t *p_struct = malloc(sizeof(*p_struct)); 而不是int main(void){...。 (这些标准确实在这里提供了回旋余地,但是显然它被更广泛地接受为适当的。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。