Ano*_*Guy 6 c type-conversion void void-pointers compiler-warnings
我收到了这条消息:
expected 'void **' but argument is of type 'char **'
Run Code Online (Sandbox Code Playgroud)
当我尝试编译类似于此的东西:
void myfree( void **v )
{
if( !v || !*v )
return;
free( *v );
*v = NULL;
return;
}
Run Code Online (Sandbox Code Playgroud)
我在堆栈溢出后阅读这个问题后发现了我认为的解决方案:
在处理双重间接时避免不兼容的指针警告 - 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;
}
Run Code Online (Sandbox Code Playgroud)
这是合法的C吗?我解除引用无效指针不是吗?
谢谢大家
编辑12/10/2010美国东部时间下午4:45:
因为它被指出free(NULL)是安全的,并由C标准涵盖.另外,如下所述,我上面的例子不合法C.请参阅caf的答案,Zack的答案和我自己的答案.
因此,我可以更容易地将任何要成为malloc的指针初始化为NULL,然后直接在代码中直接释放free()和NULL:
free( pointer );
pointer = NULL;
Run Code Online (Sandbox Code Playgroud)
我在myfree()中检查NULL的原因与我一样是因为我使用fclose()的经验.fclose(NULL)可以根据平台进行段错(例如xpsp3 msvcrt.dll 7.0.2600.5512),因此我假设(错误地)使用free()可能会发生同样的事情.我想用if语句可以更好地在函数中实现,而不是弄乱我的代码.
感谢大家所有的好评
不,这不是合法void *的 C,除非您将对象的地址传递给myfree()(所以您不妨保留原来的定义)。
原因是在您的示例中,类型的对象(在 中char *声明的对象)通过类型的左值(在 中的左值)进行修改。C 标准的 \xc2\xa76.5 规定:testmain()void **vmyfree()
\n\n\n7 对象的存储值只能由具有以下类型之一的左值表达式访问:
\n\nRun Code Online (Sandbox Code Playgroud)\n\xe2\x80\x94 a type compatible with the effective type of the object,\n\xe2\x80\x94 a qualified version of a type compatible with the effective type of \nthe object,\n\xe2\x80\x94 a type that is the signed or unsigned type corresponding to the effective\ntype of the object,\n\xe2\x80\x94 a type that is the signed or unsigned type corresponding to a qualified\nversion of the effective type of the object,\n\xe2\x80\x94 an aggregate or union type that includes one of the aforementioned\ntypes among its members (including, recursively, a member of a subaggregate\nor contained union), or\n\xe2\x80\x94 a character type.\n
由于void *和char *是不兼容的类型,因此这个限制已被打破。两种指针类型兼容的条件在\xc2\xa76.7.5.1中描述:
\n\n\n为了使两个指针类型兼容,两者都应具有相同的限定,并且都应是指向兼容类型的指针。
\n
要达到你想要的效果,必须使用宏:
\n\n#define MYFREE(p) (free(p), (p) = NULL)\nRun Code Online (Sandbox Code Playgroud)\n\n(无需检查NULL,因为free(NULL)是合法的。请注意,该宏计算p两次)。
| 归档时间: |
|
| 查看次数: |
2004 次 |
| 最近记录: |