如何在C中自动增加结构的内存分配?

如何在C中自动增加结构的内存分配?,c,memory-management,C,Memory Management,我正在构建一个以姓名和年龄作为输入(存储在结构中)并输出的小程序。我面临的一个问题是,我必须输入要存储的人数,我确信我可以用realloc()解决这个问题,但它不起作用。这是我到目前为止得到的 #include <stdio.h> #include<stdlib.h> struct info { int age; char name[30]; }; int main() { struct info *Ptr; int i, num;

我正在构建一个以姓名和年龄作为输入(存储在结构中)并输出的小程序。我面临的一个问题是,我必须输入要存储的人数,我确信我可以用
realloc()
解决这个问题,但它不起作用。这是我到目前为止得到的

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

struct info
{
    int age;
    char name[30];
};

int main()
{
    struct info *Ptr;
    int i, num;

    printf("Enter number of people");
    scanf("%d", &num);

    // Allocates the memory for num structures with pointer Ptr pointing to the base address.
    Ptr = (struct info*)malloc(num * sizeof(struct info));

    for(i = 0; i < num; ++i)
    {
        printf("Enter name and age:\n");
        scanf("%s %d", &(Ptr+i)->name, &(Ptr+i)->age);
    }


    for(i = 0; i < num ; ++i)
        printf("Name = %s, Age = %d\n", (Ptr+i)->name, (Ptr+i)->age);

    return 0;
}

如何使用realloc来避免在输入人名之前必须输入人名?

realloc
是正确的方法。只需从
Ptr=NULL
num=0
开始,在每个输入上增加一个元素的数量

请记住限制scanf可以读取的字符数,否则可能会导致缓冲区溢出

我还发现
Ptr[I]
(Ptr+I)->
更容易

还可以将字符串与未使用
的strcmp
进行比较=
=将指针与字符串进行比较,而不是字符串本身

因为我喜欢读整行,然后扫描整行,所以我会这样做:

     while(input != "stop)
    {
      allocate more memory
}
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

struct info
{
    int age;
    char name[30];
};

int main()
{
    struct info *ptr = 0;
    size_t num = 0;

    for (;;) {
        printf("Enter name and age. If you want to stop, type only 'stop'.\n");

        char line[256];
        if (fgets(line, sizeof(line), stdin) == NULL) { 
             fprintf(stderr, "fgets error");
             exit(-1);
        }

        if (!strcmp("stop\n", line)) {
             break;
        }

        struct info tmp;
        if (sscanf(line, "%29s %d\n", tmp.name, &tmp.age) != 2) {
             fprintf(stderr, "error parsing line\n");
             exit(-1);
        }

        ptr = realloc(ptr, (num + 1) * sizeof(*ptr));
        if (ptr == NULL) { 
             fprintf(stderr, "error allocating memory!\n");
             exit(-1);
        }

        ptr[num] = tmp;
        ++num;
    }


    for (size_t i = 0; i < num ; ++i) {
        printf("Name = %s, Age = %d\n", ptr[i].name, ptr[i].age);
    }

    free(ptr);

    return 0;
}
#包括
#包括
#包括
#包括
结构信息
{
智力年龄;
字符名[30];
};
int main()
{
结构信息*ptr=0;
大小\u t num=0;
对于(;;){
printf(“输入姓名和年龄。如果要停止,请只键入“停止”。\n”);
字符行[256];
如果(fgets(line,sizeof(line,stdin)==NULL){
fprintf(标准,“fgets错误”);
出口(-1);
}
如果(!strcmp(“停止\n”,第行)){
打破
}
结构信息tmp;
如果(sscanf(行,“%29s%d\n”、tmp.name和tmp.age)!=2){
fprintf(stderr,“错误分析行\n”);
出口(-1);
}
ptr=realloc(ptr,(num+1)*sizeof(*ptr));
如果(ptr==NULL){
fprintf(stderr,“分配内存时出错!\n”);
出口(-1);
}
ptr[num]=tmp;
++num;
}
对于(大小i=0;i
如果您不确定要分配的元素数量,并根据用户的选择进行分配,则可以采用以下方法

它从一个元素开始,当用户想要添加新元素时,内存被重新分配

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

struct info
{
  int age;
  char name[30];
};

int main()
{
    struct info *Ptr=NULL;
    int i=0, num;

    char c='Y';
    while(c=='Y'||c=='y') {

            Ptr=realloc(Ptr,(i+1)*sizeof(struct info));
            if(Ptr==NULL)
                 break;
            printf("Enter name and age:\n");
            scanf("%s %d",&Ptr[i].name,&Ptr[i].age);
            printf("Do you want to cont?\n");
            scanf(" %c",&c);
            i++;
    }
    num=i;

    for(i = 0; i < num ; ++i)
            printf("Name = %s, Age = %d\n", (Ptr+i)->name, (Ptr+i)->age);
    free(Ptr);
    return 0;
}
#包括
#包括
结构信息
{
智力年龄;
字符名[30];
};
int main()
{
结构信息*Ptr=NULL;
int i=0,num;
char c='Y';
而(c=='Y'| | c=='Y'){
Ptr=realloc(Ptr,(i+1)*sizeof(结构信息));
如果(Ptr==NULL)
打破
printf(“输入姓名和年龄:\n”);
scanf(“%s%d”,&Ptr[i].name,&Ptr[i].age);
printf(“您想继续吗?\n”);
scanf(“%c”、&c);
i++;
}
num=i;
对于(i=0;i名称,(Ptr+i)->年龄);
免费(Ptr);
返回0;
}

您应该使用类似于
向量的数据结构

  • vector\u init
    init vector
  • vector\u push
    push
    val
    vector
    ,如有必要,将
    realloc
    内存
  • vector\u输出
    输出
    矢量
  • 以下
    code
    可以工作:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define INIT_SIZE 1
    
    struct info
    {
        int age;
        char name[30];
    };
    
    struct vector {
        struct info* p;
        int n;
        int index;
    };
    
    void vector_init(struct vector* ve) {
        ve->n     = INIT_SIZE;
        ve->index = 0;
        ve->p     = malloc(sizeof(struct info) * ve->n);
    }
    
    void vector_push(struct vector* ve, struct info* tmp) {
        if (ve->n == ve->index) {
            ve->n *= 2;
            ve->p = realloc(ve->p, sizeof(struct info) * ve->n);
        }
        ve->p[ve->index++] = *tmp;
    }
    
    void vector_output(const struct vector* ve) {
        for (int i = 0; i < ve->index; ++i)
            printf("Name = %s, Age = %d\n", ve->p[i].name, ve->p[i].age);
    }
    
    int main()
    {
        struct vector ve;
        vector_init(&ve);
    
        for (;;) {
            struct info tmp;
            printf("Enter name and age:\n");
            scanf("%29s", tmp.name);
            if (strcmp(tmp.name, "stop") == 0)
                break;
            scanf("%d", &tmp.age);
            vector_push(&ve, &tmp);
        }
        vector_output(&ve);
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    #定义初始大小1
    结构信息
    {
    智力年龄;
    字符名[30];
    };
    结构向量{
    结构信息*p;
    int n;
    整数指数;
    };
    void vector_init(结构向量*ve){
    ve->n=初始尺寸;
    ve->index=0;
    ve->p=malloc(sizeof(struct info)*ve->n);
    }
    无效向量推送(结构向量*ve,结构信息*tmp){
    如果(ve->n==ve->index){
    ve->n*=2;
    ve->p=realloc(ve->p,sizeof(struct info)*ve->n);
    }
    ve->p[ve->index++]=*tmp;
    }
    无效向量_输出(常量结构向量*ve){
    对于(int i=0;iindex;++i)
    printf(“名称=%s,年龄=%d\n”,ve->p[i]。名称,ve->p[i]。年龄);
    }
    int main()
    {
    结构向量ve;
    向量初始化(&ve);
    对于(;;){
    结构信息tmp;
    printf(“输入姓名和年龄:\n”);
    scanf(“%29s”,tmp.name);
    if(strcmp(tmp.name,“stop”)==0)
    打破
    scanf(“%d”和tmp.age);
    向量推送(ve和tmp);
    }
    向量输出(&ve);
    返回0;
    }
    
    要准确回答问题,您可以先读取临时变量的输入,然后检查是否需要停止:如果需要,请中断循环。或者通过将“存储”阵列的大小增加1并将刚读取的值复制到“存储”阵列,继续并重新分配该阵列

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct          info
    {
      int           age;
      char          name[30];
    };
    
    int             main()
    {
      struct info * infos = 0;
      int           num = 0;
      char          input_name[30];
      int           input_age;
    
      while (1)
        {
          printf("Enter name and age:\n");
          int r = scanf("%29s", input_name);
          if (r == EOF || strcmp(input_name, "stop") == 0)
            break;
          scanf(" %d", &input_age);
    
          infos = realloc(infos, sizeof(struct info) * (num + 1));
          infos[num].age = input_age;
          memcpy(infos[num].name, input_name, sizeof(char) * 30);
          num++;
        }
    
      for(int i = 0; i < num ; ++i)
        printf("Name = %s, Age = %d\n", infos[i].name, infos[i].age);
    
      return 0;
    }
    
    #包括
    #包括
    #包括
    结构信息
    {
    智力年龄;
    字符名[30];
    };
    int main()
    {
    结构信息*infos=0;
    int num=0;
    字符输入_名称[30];
    输入年龄;
    而(1)
    {
    printf(“输入姓名和年龄:\n”);
    int r=scanf(“%29s”,输入名称);
    如果(r==EOF | | strcmp(输入|名称,“停止”)==0)
    打破
    scanf(“%d”,输入时间(&U);
    infos=realloc(infos,sizeof(struct info)*(num+1));
    infos[num].age=input\u age;
    memcpy(infos[num].name,input_name,sizeof(char)*30);
    num++;
    }
    对于(int i=0;i
    我知道,但在我能够以正确的方式执行realoc之前,我无法做到这一点。在我能够继续比较结构和输入变量的输入之前,你能清楚地解释一下你想要实现什么吗?你不想接受人数,然后在人数增加时进行调整,这就是你想要实现的吗?“它不起作用”实际上不起作用的东西?虽然realloc允许你扩大分配,但它可能非常低效。如果记录不需要位于连续内存中,则可以使用链表。添加记录既快速又高效,acces