如何解决void* 与 char* 具有相同的表示和内存对齐是什么意思?
我一直在阅读一些关于 void*
类型指针的文章,并从标准中找到了这个要求。
6.2.5.27:
指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。39) 同样,指向兼容类型的限定或非限定版本的指针应具有相同的表示和对齐要求。
我看到标准不保证所有指针类型都具有相同的长度,所以这里的底线是 void*
指针具有与 char*
相同的长度和对齐规则,对吗?
我不明白的是脚注 39),它说
相同的表示和对齐要求意味着作为函数的参数、函数的返回值和联合成员的可互换性。
我的问题是:
-
“可互换性”是什么意思?它是说函数
void* Func(void*)
的参数和返回值都可以是char*
吗? -
如果是,是否是编译器进行的隐式转换?
-
工会成员的情况如何?实在搞不懂这句话的意思。谁能给我举个简单的例子?
解决方法
在 C 中,任何数据指针都可以传递给需要 void *
的函数,而 void *
可以存储到任何指针类型。 void *
和其他指针类型之间存在隐式转换。但这并不意味着这种转换是无害的。在某些 void *
和 int *
具有不同表示的体系结构上,从 int *
转换为 void *
然后再转换回 int *
被指定为产生相同的指针值,但反过来不成立:将 void *
转换为 int *
并返回 void *
可能会产生不同的值,特别是如果 void *
不是通过转换 int *
获得的{1}}。
可互换性意味着这种隐式转换不会改变指针的表示。转换可以通过两种方式成功进行:将字符指针转换为 void *
并返回产生相同的指针,反之亦然。
这是一个例子:
#include <assert.h>
#include <stdio.h>
#include <string.h>
int main() {
char *s = "abc";
char *s1;
void *p;
void *p1;
assert(sizeof(p) == sizeof(s));
memcpy(&p,&s,sizeof(p));
p1 = s;
assert(p == p1);
memcpy(&s1,&p1,sizeof(s1));
assert(s == s1);
return 0;
}
但是请注意,这并不意味着 !memcmp(&p1,sizeof(p1))
,因为指针可能具有填充位。您也不能通过 void *
进行强制转换来违反严格的别名规则:
-
float f = 1.0; unsigned int i = *(int *)(void *)&f'
不正确。 -
float f = 1.0; unsigned int i; memcpy(&i,&f,sizeof(i));
在sizeof(int) == sizeof(float)
时更正,但可能会产生陷阱值。
指针只是内存中的一个地址。您可以认为内存是一个字节的连续区域,它非常大(例如,在 32 位进程上它将是 4 GB,但通常该进程无法使用整个区域,这取决于系统)。
这意味着指针的值实际上是一个整数,表示内存中一个字节的从零开始的索引(例如,值为 0
的指针指的是内存中的第一个字节,但实际上你不会由于它是一个空指针,因此能够取消引用该地址)。
当您取消引用一个指针时,它的作用是读取/写入该地址。读/写的大小取决于指针的类型。如果一个指针是 int
并且它在那个系统上的大小是 32 位,也就是 4 个字节;它将从该地址开始读/写 4 个字节。对齐的意思是值如何存储在内存中。假设存储在内存中的值需要是 16 字节对齐,这意味着它的起始地址必须乘以 16。
我这里解释的只是一个高级的指针,应该足够入门了。实际上它有很多相关的东西,比如内存保护、分页等。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。