You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过memcpy将void指针存入其他类型指针是否触发未定义行为?

使用memcpy跨指针类型存储与恢复void指针的合法性分析

问题描述

尝试通过memcpy(而非强制类型转换)将void指针存入其他类型的指针变量中,之后再恢复原void指针,这种操作是否会触发未定义行为?

示例验证代码

#include <assert.h>
#include <string.h>
#include <stdio.h>

int main()
{
    // 确保int指针足够容纳void指针
    _Static_assert( sizeof( int* ) >= sizeof( void* ) );
    
    // 创建指向哑值的void指针
    void *a = &(short){ 10 };
    
    // 通过memcpy将void指针存入int指针
    int *b = NULL;
    memcpy( &b, &a, sizeof( void *) );
    
    // 通过赋值复制int指针
    // 可能存在未定义行为:b可能是无效int指针,或赋值未复制关键填充位?
    int *c = b;
    
    // 从复制的int指针中提取void指针
    void *d;
    memcpy( &d, &c, sizeof( void *) );
    
    // 提取的void指针应与原指针一致,因此该行应输出10
    printf( "%d", *(short *)d );

    return 0;
}

应用场景示例

这种思路的目的是将malloc分配的指针存入其他类型指针,后续在未知该类型的函数中恢复原指针,示例代码如下:

#include <stdlib.h>
#include <string.h>

void alloc_mem( void *p )
{
    void *mem = malloc( 100 );
    memcpy( p, &mem, sizeof( void * ) );
}

void do_something_with_mem( void *p )
{
    void *mem;
    memcpy( &mem, p, sizeof( void * ) );
    if( mem )
    {
        // 使用mem执行操作
    }
}

int main()
{
    // 此处用int仅作演示,可为任意类型
    _Static_assert( sizeof( int* ) >= sizeof( void* ) );
    int *foo = NULL;
    
    alloc_mem( &foo );
    
    int *bar = foo;
    do_something_with_mem( &bar );

    return 0;
}

结论与分析

这种操作不会触发未定义行为,核心依据如下:

  • 存储前提合法:C标准规定,只要目标指针类型的存储空间不小于void*的尺寸,就可以通过memcpy将void*的字节内容完整存入其中。代码中的_Static_assert已经确保了这一前提,避免了存储空间不足的问题。

  • 指针赋值无风险:将存储了void*字节的int* b赋值给int* c时,只是完整复制b的所有字节(包括可能的填充位)。C标准要求指针赋值必须完整复制其存储的全部内容,因此不会出现“丢失关键位”的情况。需要注意的是:此时b并非有效的int指针,但仅仅持有或复制这个值并不会触发未定义行为——只有当你试图将其当作真正的int指针解引用时,才会出现问题,而示例代码中并未执行此类操作。

  • 恢复原指针的正确性:通过memcpy从int* c恢复void* d时,只是将之前存储的字节原样复制回来。C标准保证,只要void*的字节被完整保存并原样恢复,得到的指针与原指针完全等价,可正常使用。

  • 场景扩展的合法性:第二个示例的逻辑与第一个完全一致,只要保证目标指针类型尺寸不小于void*,且全程仅做字节复制、不将存储了void*内容的指针当作对应类型指针解引用,整个流程就完全符合C标准要求。

内容的提问来源于stack exchange,提问作者Jackson Allan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 15:05:34