C中转换为(char *)和*(char **)之间的区别(实现malloc)

时间:2015-12-01 21:15:13

标签: c pointers malloc

我遇到了一些使用这两种代码的代码,看似可以互换。

我会举一个我很困惑的例子:

假设我在双向链表中有一些数据,我想更改一个块中的某些字符/地址。所以我们有:

void* ptr; //points to beginning of block
void* prevPtr; //prev item in LL
void* nextPtr; //next item in LL
*((char *)ptr) = prevPtr;
*(*(char **)(ptr) + sizeof(char*)) = nextPtr;

在这个例子中,底部的两行之间有什么区别(除了明显移动到内存中nextPtr的位置)?

2 个答案:

答案 0 :(得分:3)

*((char *)ptr) = prevPtr;与:

相同
char *temp = ptr;
*temp = prevPtr;

这是不正确的,因为您正在尝试指定一个字符指针。

*(*(char **)(ptr) + sizeof(char*)) = nextPtr;与:

相同
char **t1 = ptr;
char *t2 = *t1;
t2[4] = nextPtr;    // assuming 4-byte pointers

这也是一个错误的形式,因为它指定了一个指向角色的指针。

在这两种情况下,您都应该收到有关此错误的编译器消息(不要被gcc误导,即使代码实际上是错误,也会对不兼容的类型转换发出“警告”)。

void *是通用指针类型。它用于具有用于传输各种指针类型的接口的位置。但是,您只能将void *转换回它来自的指针类型。任何其他指针转换都不能保证正常工作,如果转换为具有不同*个数的指针类型,则特别可能无法执行预期的操作。

为了帮助您决定在代码中执行哪些操作,您必须首先查看ptr的分配方式。

答案 1 :(得分:1)

在第一个中,ptr被转换为指向char然后prevPtr的指针,而不是指向prevPtr的指针,但指定了它存储的地址,到当前指向的字符类型的内存位置ptr。在第二个中,ptr被强制转换为指向char的指针,然后在添加偏移量之前取消引用,这将导致nextPtr的值(不是它指向的值)在ptr指向的位置之后写入一个指针大小的偏移量,在您的示例中该位置仍应是一个字符。换句话说,您的示例代码没有意义,但希望我的详细说明有助于您理解。