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

仅知数组大小上限时如何创建动态数组?malloc不可部分释放

已知大小上限、实际元素数事后确定时的数组创建方案

核心错误说明

你之前尝试用free(p+j)释放多余内存的做法是完全错误的——free的参数必须是malloc/calloc/realloc返回的原始指针,不能是指针偏移后的地址,否则会触发未定义行为(比如内存损坏、程序崩溃)。

正确方案一:用realloc调整内存大小

先按上限分配内存,待确定实际有效元素数j后,通过realloc将内存块缩小到实际需要的尺寸:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 按上限分配内存
    int max_size = 1000;
    int* arr = malloc(max_size * sizeof(int));
    if (arr == NULL) {
        perror("malloc failed");
        return 1;
    }

    // 模拟填充元素,假设实际有效元素数为j
    int j = 0;
    for (int num = 2; num < 100; num++) { // 示例:统计100以内的素数
        int is_prime = 1;
        for (int i = 2; i*i <= num; i++) {
            if (num % i == 0) {
                is_prime = 0;
                break;
            }
        }
        if (is_prime) {
            arr[j++] = num;
        }
    }

    // 调整内存到实际需要的大小
    int* temp = realloc(arr, j * sizeof(int));
    if (temp != NULL) {
        arr = temp; // 调整成功,更新指针
    } else {
        // 调整失败时,原内存仍可用,可选择继续使用或释放
        fprintf(stderr, "realloc failed, using original memory block\n");
    }

    // 使用数组
    for (int i = 0; i < j; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // 释放内存(无论是否调整成功,都用最终的arr指针)
    free(arr);
    return 0;
}
  • 注意:必须用临时指针接收realloc的返回值,避免调整失败时丢失原内存指针导致泄漏。
  • realloc会自动处理多余内存的释放,无需手动操作。

正确方案二:先统计实际大小,再分配内存

如果场景允许(比如素数统计),可以先遍历一次统计实际需要的元素数量,再精准分配内存:

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

// 统计n以内素数的数量
int count_primes(int n) {
    if (n <= 2) return 0;
    char* is_prime = malloc(n * sizeof(char));
    if (is_prime == NULL) return 0;
    memset(is_prime, 1, n);
    is_prime[0] = is_prime[1] = 0;

    for (int i = 2; i*i < n; i++) {
        if (is_prime[i]) {
            for (int j = i*i; j < n; j += i) {
                is_prime[j] = 0;
            }
        }
    }

    int count = 0;
    for (int i = 2; i < n; i++) {
        if (is_prime[i]) count++;
    }
    free(is_prime);
    return count;
}

int main() {
    int n = 100;
    int prime_count = count_primes(n);
    if (prime_count == 0) {
        printf("No primes found\n");
        return 0;
    }

    // 精准分配内存
    int* primes = malloc(prime_count * sizeof(int));
    if (primes == NULL) {
        perror("malloc failed");
        return 1;
    }

    // 再次遍历填充素数
    char* is_prime = malloc(n * sizeof(char));
    memset(is_prime, 1, n);
    is_prime[0] = is_prime[1] = 0;
    for (int i = 2; i*i < n; i++) {
        if (is_prime[i]) {
            for (int j = i*i; j < n; j += i) {
                is_prime[j] = 0;
            }
        }
    }

    int idx = 0;
    for (int i = 2; i < n; i++) {
        if (is_prime[i]) {
            primes[idx++] = i;
        }
    }
    free(is_prime);

    // 使用数组
    for (int i = 0; i < prime_count; i++) {
        printf("%d ", primes[i]);
    }
    printf("\n");

    free(primes);
    return 0;
}
  • 这个方案内存使用更精准,没有浪费,但需要额外一次统计遍历,对于大多数计算场景来说,这种开销完全可接受。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:10:40