C++用new int[size]分配动态数组:size是否需预先确定?能否修改n值?示例是否合法?
核心规则说明
new int[size]的size不需要在代码执行前预先写死成固定的编译期常量。
new[]申请堆内存时,只要求操作数是执行到对应代码行时,可正常计算得到的合法正整数即可:不管这个size是用户运行时输入的、还是前面业务逻辑计算出来的,都完全符合C++标准,和C语言栈上分配的可变长数组(VLA)的规则有本质区别。
能否直接调整n的值?
执行int* array = new int[n];之后,单独修改变量n本身,完全不会改变已经分配完成的动态数组的大小。
new[]的执行逻辑是:运行到这行代码的瞬间,读取当前n的数值,向系统申请对应大小的堆内存,把内存块的起始地址返回给指针。- 之后哪怕你把n改成1、改成100万,已经申请完成的那块内存的大小是固定的,不会跟着n的变化自动扩展或者收缩。如果要调整已分配数组的大小,必须重新申请合适大小的新内存块、把旧数据拷贝过去、再释放旧内存,不可能靠直接修改原size变量实现。
给出的示例代码存在的问题
这段代码完全不符合规范,存在严重的未定义行为风险,和ArrSize是不是预先固定没有关系,核心是内存分配时机和逻辑错配:
- 执行
int* newArr = new int[ArrSize];的瞬间,程序已经按照当时初始的ArrSize数值,申请了固定大小的堆内存。 - 后续循环里每遇到一个正元素就执行
ArrSize++,这个操作根本不会让已经分配好的newArr内存块扩大。如果实际统计到的正元素数量超过了初始分配的ArrSize上限,执行newArr[j] = arr[i]时,j会超出已分配内存的下标范围,直接造成越界写入,触发缓冲区溢出、内存数据被破坏这类未定义行为。 - 就算初始ArrSize给的足够大,循环里修改的ArrSize只是函数内的局部变量,函数返回后,外部根本拿不到newArr的实际有效长度——既不能从指针反推堆内存的大小,也没法靠这个修改过的局部变量把长度传出去,后续使用返回的数组时完全不知道访问边界在哪。
- 正确的实现逻辑要么是:先完整遍历一次原数组,统计出所有符合条件的正元素总数量,用这个统计值作为size再去申请对应大小的内存;要么直接使用标准库提供的
std::vector,由容器自动完成动态扩容、内存管理,不需要手动计算size、手动维护内存边界。
内容的提问来源于stack exchange,提问作者user15402511
相关产品推荐
相关产品推荐

