如何一般蒙上了指针的地址,同时符合C标准 [英] How to cast the address of a pointer generically while conforming to the C standard

查看:118
本文介绍了如何一般蒙上了指针的地址,同时符合C标准的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是共同使用隐函数,返回void与分配分配指针*转换,就像的malloc()的:

 的void * malloc的(为size_t大小);
INT * PI =的malloc(sizeof的* PI);

我想执行的同时传递目标指针的地址相同的分配,并没有从函数内显式铸造它的类型(而不是它的身体内,也没有参数)。

以下code似乎实现了这一点。


  1. 我想知道code是否完全符合(任意)
    对C类标准。

  2. 如果它不符合,我想知道是否有可能
    达到我的要求,同时符合(任何)的C类标准。

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;INT allocate_memory(无效* P,为size_t S){
    无效* PV;
    如果((PV =的malloc(S))== NULL){
        fprintf中(标准错误,错误:的malloc(););
        返回-1;
    }
    的printf(PV:%P; \\ N,PV);
    *((无效**)P)= PV;
    返回0;
}诠释主要(无效){
    INT * PI = NULL;
    allocate_memory(安培; PI,siz​​eof的* PI);
    的printf(PI:%P; \\ N(无效*)PI);
    返回0;
}

结果:

  PV:0x800103a8;
PI:0x800103a8;


解决方案

没有,这是不符合。你传递一个 INT ** 无效* (OK),但是你投了无效* 无效** 这是不能保证具有相同的大小和布局。您只能取消引用无效* (除了得到1的malloc / 释放calloc )后,将其转换回它原本是指针类型,这个规则并不适用于递归(所以无效** 不会自动转换,像无效* )。

我还没有看到一个方式,以满足您的所有需求。如果您必须通过指针传递一个指针,那么你需要实际通过的无效* 地址和做所有必要的铸造在调用者,在这种情况下。这将是

  INT * PI;
无效* PV;
allocate_memory(安培; PV,sizeof的(INT));
PI = PV;

...你打败方案。

It is common to assign pointers with allocations using an implicit function-return void * conversion, just like malloc()'s:

void *malloc(size_t size);
int *pi = malloc(sizeof *pi);

I would like to perform the same assignment while passing the address of the target pointer, and without explicitly casting its type from within the function (not within its body, nor arguments).

The following code seems to achieve just that.

  1. I would like to know whether the code fully conforms with (any of) the C standards.
  2. If it doesn't conform, I would like to know if it's possible to achieve my requirement while conforming to (any of) the C standards.

.

#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;
}

Result:

pv: 0x800103a8;
pi: 0x800103a8;

解决方案

No, this is not compliant. You're passing an int** as void* (ok), but then you cast the void* to a void** which is not guaranteed to have the same size and layout. You can only dereference a void* (except one gotten from malloc/calloc) after you cast it back to the pointer type that it originally was, and this rule does not apply recursively (so a void** does not convert automatically, like a void*).

I also don't see a way to meet all your requirements. If you must pass a pointer by pointer, then you need to actually pass the address of a void* and do all the necessary casting in the caller, in this case main. That would be

int *pi;
void *pv;
allocate_memory(&pv, sizeof(int));
pi = pv;

... defeating your scheme.

这篇关于如何一般蒙上了指针的地址,同时符合C标准的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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