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

动态内存分配下向数组添加元素的实现问题

静态数组添加元素的问题分析与修正方案

核心问题分析

  • 静态数组无法用realloc扩容:feld是栈上分配的静态数组(student_t feld[N]),realloc仅适用于堆内存(通过malloc/calloc分配的内存),你声明的ptr和feld毫无关联,这是根本错误。
  • 输入新元素时覆盖了第一个元素:&feld->nummer等价于&feld[0].nummer,输入的新学号会直接覆盖数组第一个元素的学号,而非添加到末尾。
  • 字符串赋值方式错误:feld[7].name = {"Linas Dagys"}; 是非法操作,C语言中char数组不能直接用=赋值字符串,必须用strcpy函数。
  • 语法错误:feld[7].nummer) = 50846; 多了一个右括号,会导致编译失败。

修正方案(两种选择)

方案1:继续使用静态数组(利用剩余空间)

你定义的N=20,当前仅用了6个元素,还有14个空闲位置,直接往数组末尾添加即可,无需扩容:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> 
#include <stdlib.h>
#include <string.h> // 新增strcpy所需头文件

#define MAX_NAME_LEN 50
#define N 20
    
struct student {
    unsigned int nummer;
    char name[MAX_NAME_LEN];
};
    
typedef struct student student_t;
    
int element_vergleich(const void* p1, const void* p2)
{
    student_t* sp1 = (student_t*)p1;
    student_t* sp2 = (student_t*)p2;
    if (sp1->nummer < sp2->nummer)
        return -1;
    else if (sp1->nummer > sp2->nummer)
        return 1;
    else
        return 0;
}
    
void sortiere(student_t* f, int n)
{
    qsort(f, n, sizeof(student_t), element_vergleich);
}
    
int main(void)
{
    student_t feld[N] = { {59112, "Peter Lustig"}, {45181, "Fritz Fuchs"}, {38984, "Bibi Blocksberg"},
                            {87191, "Bernd Brot"}, {58731, "Katie Sommer"}, {75442, "Hein Klug"} };
    int n = 6;   // 当前已使用元素数量

    printf("Das Feld wurde fuer %d Elemente deklariert. Davon werden %d Elemente benutzt.\n", N, n);
    
    for (int i = 0; i < n; i++)
    {       
        printf("Element [%d]: Matrikelnummer: %u\tName Student: %s\n", i + 1, feld[i].nummer, feld[i].name);
    }

    // 检查是否还有剩余空间
    if (n >= N) {
        printf("数组已满,无法添加新元素!\n");
        return 1;
    }

    // 输入新元素到数组末尾(索引n的位置)
    printf("Geben Sie einen neuen Studenten ein.\n");
    printf("Geben Sie Matrikelnummer ein: ");
    scanf("%u", &feld[n].nummer); // 使用%u匹配unsigned int
    printf("Geben Sie Name des Studenten ein: ");
    scanf("%s", feld[n].name); // feld[n].name本身就是数组首地址,无需&

    // 手动添加另一个元素(示例)
    n++; // 先增加计数,再赋值
    feld[n-1].nummer = 50846;
    strcpy(feld[n-1].name, "Linas Dagys"); // 使用strcpy复制字符串

    n++; // 元素计数更新为8

    // 排序并输出结果
    sortiere(feld, n);
    printf("\n添加新元素后的排序结果:\n");
    for (int i = 0; i < n; i++)
    {       
        printf("Element [%d]: Matrikelnummer: %u\tName Student: %s\n", i + 1, feld[i].nummer, feld[i].name);
    }
    
    return 0;
}

方案2:改用动态分配数组(支持真正扩容)

如果需要超出N的限制动态扩容,必须一开始就用堆内存:

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

#define MAX_NAME_LEN 50
    
struct student {
    unsigned int nummer;
    char name[MAX_NAME_LEN];
};
    
typedef struct student student_t;
    
int element_vergleich(const void* p1, const void* p2)
{
    student_t* sp1 = (student_t*)p1;
    student_t* sp2 = (student_t*)p2;
    if (sp1->nummer < sp2->nummer)
        return -1;
    else if (sp1->nummer > sp2->nummer)
        return 1;
    else
        return 0;
}
    
void sortiere(student_t* f, int n)
{
    qsort(f, n, sizeof(student_t), element_vergleich);
}
    
int main(void)
{
    // 初始动态分配6个元素的空间
    student_t* feld = malloc(sizeof(student_t) * 6);
    if (!feld) { // 检查内存分配是否成功
        printf("内存分配失败!\n");
        return 1;
    }

    // 初始化元素
    feld[0] = (student_t){59112, "Peter Lustig"};
    feld[1] = (student_t){45181, "Fritz Fuchs"};
    feld[2] = (student_t){38984, "Bibi Blocksberg"};
    feld[3] = (student_t){87191, "Bernd Brot"};
    feld[4] = (student_t){58731, "Katie Sommer"};
    feld[5] = (student_t){75442, "Hein Klug"};

    int n = 6;   // 当前元素数量
    int capacity = 6; // 当前数组容量

    printf("当前数组容量:%d,已使用元素数量:%d\n", capacity, n);
    
    for (int i = 0; i < n; i++)
    {       
        printf("Element [%d]: Matrikelnummer: %u\tName Student: %s\n", i + 1, feld[i].nummer, feld[i].name);
    }

    // 扩容:增加到8个元素的容量
    student_t* temp = realloc(feld, sizeof(student_t) * 8);
    if (!temp) { // 检查扩容是否成功,避免原内存泄漏
        printf("扩容失败!\n");
        free(feld);
        return 1;
    }
    feld = temp;
    capacity = 8;

    // 输入新元素
    printf("Geben Sie einen neuen Studenten ein.\n");
    printf("Geben Sie Matrikelnummer ein: ");
    scanf("%u", &feld[n].nummer);
    printf("Geben Sie Name des Studenten ein: ");
    scanf("%s", feld[n].name);
    n++;

    // 添加另一个示例元素
    feld[n].nummer = 50846;
    strcpy(feld[n].name, "Linas Dagys");
    n++;

    // 排序并输出
    sortiere(feld, n);
    printf("\n添加新元素后的排序结果:\n");
    for (int i = 0; i < n; i++)
    {       
        printf("Element [%d]: Matrikelnummer: %u\tName Student: %s\n", i + 1, feld[i].nummer, feld[i].name);
    }

    free(feld); // 释放动态分配的内存
    
    return 0;
}

关键注意点

  • 静态数组的大小在编译时就固定,无法动态扩容,只能使用预定义的剩余空间。
  • realloc必须用于堆内存,且扩容时要先接收返回值到临时指针,避免分配失败时丢失原内存地址。
  • char数组赋值字符串必须用strcpy,不能直接用=。
  • 处理unsigned int类型时,scanf要使用%u格式符,避免类型不匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:42:51