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

动态数组添加长整数时出现内存分配错误,求问题排查

问题分析与修复

你的代码核心问题是数组越界操作破坏了堆内存结构,同时还有其他内存管理和逻辑错误,以下是具体问题和修复方案:

主要错误点

1. 数组越界读写,直接破坏堆

找到因数时的内存复制逻辑完全错误:

  • 当你创建长度为++dnum的temp数组后,执行memcpy(temp, divisors, dnum * sizeof(long)),但此时旧的divisors数组长度是dnum-1(上一次的因数个数),你读取了超出旧数组范围的内存。
  • 更严重的是memcpy(temp + dnum, added_array, sizeof(long)):temp数组的有效索引是0到dnum-1,temp + dnum已经超出数组边界,越界写入会直接破坏堆的元数据,触发free()错误或断言失败。

2. 多余的内存分配与泄漏

added_array是完全不必要的临时数组,而且你注释了它的释放代码,导致每次找到因数都会泄漏4/8字节的内存。

3. 越界访问数组末尾

printf("Final number = %ld\n", divisors[num-1]);中,divisors数组的实际长度是因数个数dnum,而num-1远大于dnum-1(比如num=100,因数个数只有9个),这会越界访问未知内存,导致程序崩溃或输出垃圾值。

4. 参数类型不匹配

main中输入的是long num,但function的参数是int num,如果输入数值超过int的范围(如大于2^31-1),会被截断,导致逻辑错误。

修复后的代码(手动内存管理版)

#include <cstdlib>
#include <iostream>
#include <cstring>

int function(long num) {
  int dnum = 0;
  long* divisors = nullptr;

  for (long i = 1; i <= num; i++) {
    if (num % i == 0) {
      // 创建长度+1的新数组
      long* temp = new long[dnum + 1];
      // 复制旧数组的所有元素(仅当旧数组非空时)
      if (dnum > 0) {
        memcpy(temp, divisors, dnum * sizeof(long));
      }
      // 添加新因数到数组末尾
      temp[dnum] = i;
      // 释放旧数组
      delete[] divisors;
      // 更新指针和计数
      divisors = temp;
      dnum++;

      printf("dnum = %d\n", dnum);
      printf("new num = %ld\n", i);
    }
  }

  if (dnum > 0) {
    printf("Final number = %ld\n", divisors[dnum - 1]);
    delete[] divisors;
  } else {
    printf("No divisors found\n");
  }
  return dnum;
}

int main() {
  long num;
  std::cin >> num;
  int result = function(num);
  printf("%d\n", result);
  return 0;
}

更简洁安全的版本(使用std::vector)

C++中推荐用std::vector自动管理内存,完全避免手动分配释放的错误:

#include <iostream>
#include <vector>

int function(long num) {
  std::vector<long> divisors;

  for (long i = 1; i <= num; i++) {
    if (num % i == 0) {
      divisors.push_back(i);
      printf("dnum = %zu\n", divisors.size());
      printf("new num = %ld\n", i);
    }
  }

  if (!divisors.empty()) {
    printf("Final number = %ld\n", divisors.back());
  } else {
    printf("No divisors found\n");
  }
  return divisors.size();
}

int main() {
  long num;
  std::cin >> num;
  int result = function(num);
  printf("%d\n", result);
  return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:13:13