Dro*_* K. 11 c pointers strict-aliasing
通常使用隐式函数返回void*转换为分配指定指针,就像malloc()一样:
void *malloc(size_t size);
int *pi = malloc(sizeof *pi);
Run Code Online (Sandbox Code Playgroud)
我希望在传递目标指针的地址时执行相同的赋值,而不从函数内部(不在其体内,也不在参数中)显式地转换其类型.
以下代码似乎实现了这一点.
.
#include <stdio.h>
#include <stdlib.h>
int allocate_memory(void *p, size_t s) {
void *pv;
if ( ( pv = malloc(s) ) == NULL ) {
fprintf(stderr, "Error: malloc();");
return -1;
}
printf("pv: %p;\n", pv);
*((void **) p) = pv;
return 0;
}
int main(void) {
int *pi = NULL;
allocate_memory(&pi, sizeof *pi);
printf("pi: %p;\n", (void *) pi);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果:
pv: 0x800103a8;
pi: 0x800103a8;
Run Code Online (Sandbox Code Playgroud)
类型int**和void**不兼容您正在将其实际类型为int**的p转换为void**,然后在此处取消引用它:
*((void **) p) = pv;
Run Code Online (Sandbox Code Playgroud)
这将破坏别名规则.
您可以传递一个void指针然后正确地转换它:
void *pi = NULL;
int* ipi = NULL ;
allocate_memory(&pi, sizeof *ipi );
ipi = pi ;
Run Code Online (Sandbox Code Playgroud)
或返回一个void指针.
int *pi = allocate_memory(sizeof *pi);
Run Code Online (Sandbox Code Playgroud)
可以选择使用联合:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
union Pass
{
void** p ;
int** pi ;
} ;
int allocate_memory(union Pass u , size_t s) {
void *pv;
if ( ( pv = malloc(s) ) == NULL ) {
fprintf(stderr, "Error: malloc();");
return -1;
}
printf("pv: %p;\n", pv);
*(u.p) = pv;
return 0;
}
int main()
{
int* pi = NULL ;
printf("%p\n" , pi ) ;
allocate_memory( ( union Pass ){ .pi = &pi } , sizeof( *pi ) ) ;
printf("%p\n" , pi ) ;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
据我了解,这个例子符合标准.
使用静态断言来保证大小和对齐方式相同.
_Static_assert( sizeof( int** ) == sizeof( void** ) , "warning" ) ;
_Static_assert( _Alignof( int** ) == _Alignof( void** ) , "warning" ) ;
Run Code Online (Sandbox Code Playgroud)
不,这不合规.你正在传递int**as void*(ok),但是然后你将其void*转换void**为不保证具有相同大小和布局的a.在将其转换回原来的指针类型后,您只能取消引用void*(除了从malloc/ 获得的一个calloc),并且此规则不会递归应用(因此a void**不会自动转换,如a void*).
我也没有办法满足你的所有要求.如果必须通过指针传递指针,那么void*在这种情况下,您需要实际传递a的地址并在调用者中执行所有必要的转换main.那就是
int *pi;
void *pv;
allocate_memory(&pv, sizeof(int));
pi = pv;
Run Code Online (Sandbox Code Playgroud)
......打败你的计划.
| 归档时间: |
|
| 查看次数: |
554 次 |
| 最近记录: |