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

将指针强制转换为数组指针是否属于未定义行为(UB)?

关于数组指针强制转换的未定义行为与类型别名问题

结论

将new int[N]返回的int*强制转换为int(*)[N]属于未定义行为,且违反C++的类型别名规则。

原因分析

  1. 类型匹配要求
    C++标准规定,通过指针访问对象时,指针类型必须与对象实际类型兼容(仅少数例外如void*、字符类型指针允许跨类型访问)。new int[10]分配的是int[10]类型的数组,但new[]返回的是指向数组首元素的int*,而非指向整个数组的int(*)[10]。

强制转换后,n被解释为指向int[10]对象的指针,但它实际指向的是单个int(数组的第一个元素)。后续执行*n[1] = 1时,n[1]会偏移sizeof(int[10])字节,访问原数组之外的内存,直接触发越界访问,属于明确的未定义行为。

  1. 指针类型的本质差异
    int*和int(*)[10]是完全不同的指针类型:
  • int*的算术操作以sizeof(int)为单位偏移;
  • int(*)[10]的算术操作以sizeof(int)*10为单位偏移。

这种类型不匹配的转换,会导致所有基于该指针的操作都脱离标准的行为保障,哪怕你认为只是“补充大小信息”,实际上已经改变了指针的核心语义。

正确实现方式

如果需要在指针中明确数组大小并安全操作,推荐以下方案:

  • 使用std::array(编译期固定大小):
    #include <array>
    int main() {
        std::array<int, 10> arr{};
        arr[1] = 1; // 类型安全,大小明确
    }
    
  • 使用std::vector(动态大小):
    #include <vector>
    int main() {
        std::vector<int> vec(10);
        vec[1] = 1; // 运行时可查询大小,避免越界风险
    }
    
  • 直接分配数组指针(若必须使用裸指针):
    int main() {
        // 直接分配包含1个int[10]的数组,返回指向整个数组的指针
        int (*n)[10] = new int[1][10];
        (*n)[1] = 1; // 先解引用数组指针,再访问元素
        delete[] n; // 对应new[]的释放
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:01:17