gpt4 book ai didi

C题: single dereference on a void** double indirection pointer

转载 作者:太空狗 更新时间:2023-10-29 17:21:48 25 4
gpt4 key购买 nike

我收到这条消息:

expected 'void **' but argument is of type 'char **'

当我尝试编译类似这样的东西时:

void myfree( void **v )
{
if( !v || !*v )
return;

free( *v );
*v = NULL;

return;
}



在阅读关于堆栈溢出的这个问题后,我找到了我认为是解决方案的方法:
Avoid incompatible pointer warning when dealing with double-indirection - Stack Overflow

所以我调整成这样:

#include <stdio.h>
#include <stdlib.h>

void myfree( void *x )
{
void **v = x;

if( !v || !*v )
return;

free( *v );
*v = NULL;

return;
}

int main( int argc, char *argv[] )
{
char *test;

if( ( test = malloc( 1 ) ) )
{
printf( "before: %p\n", test );
myfree( &test );
printf( "after: %p\n", test );
}

return 0;
}

这是合法的 C 吗?我正在取消引用 void 指针,不是吗?

谢谢大家


编辑美国东部时间 2010 年 12 月 10 日下午 4:45:
正如已经指出的那样,free(NULL) 是安全的并且包含在 C 标准中。此外,正如下面所讨论的,我上面的示例不是合法的 C。请参阅 caf 的答案、Zack 的答案和我自己的答案。

因此,我将更容易将任何待 malloc 的指针初始化为 NULL,然后直接在代码中将其初始化为 free() 和 NULL:

free( pointer );
pointer = NULL;

我之所以像以前那样在 myfree() 中检查 NULL,是因为我使用 fclose() 的经验。 fclose(NULL) 可能会出现段错误,具体取决于平台(例如 xpsp3 msvcrt.dll 7.0.2600.5512),所以我曾(错误地)假设 free() 会发生同样的事情。我曾想过,与其用 if 语句弄乱我的代码,不如在函数中更好地实现它。

感谢大家的积极讨论

最佳答案

不,这是合法的 C,除非您将 void * 对象的地址传递给 myfree()(因此您可能以及只保留您的原始定义)。

原因是在您的示例中,char * 类型的对象(在 main() 中声明为 test 的对象)是通过 void * 类型的左值修改(myfree() 中的左值 *v)。 C 标准的 §6.5 指出:

7 An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of
the object,
— a type that is the signed or unsigned type corresponding to the effective
type of the object,
— a type that is the signed or unsigned type corresponding to a qualified
version of the effective type of the object,
— an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a subaggregate
or contained union), or
— a character type.

因为 void *char * 不是兼容的类型,这个约束已经被打破。 §6.7.5.1 描述了两种指针类型兼容的条件:

For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.

要达到你想要的效果,必须使用宏:

#define MYFREE(p) (free(p), (p) = NULL)

(不需要检查 NULL,因为 free(NULL) 是合法的。注意这个宏对 p 求值两次) .

关于C题: single dereference on a void** double indirection pointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4371232/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com