简体   繁体   English

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

[英]How can i automatically increase memory allocation for a struct in C?

I am building a small program that takes name and age as input (stored in a struct) and spits out the output. 我正在构建一个小程序,将姓名和年龄作为输入(存储在结构中)并吐出输出。 One of the problems that I am facing is I have to enter the number of people I am going to store, something that I am sure I can solve with realloc() it's just not working. 我面临的问题之一是我必须输入要存储的人数,我确定我可以使用realloc()解决此问题,但它只是无法正常工作。 Here is what I got so far. 这是我到目前为止所得到的。

#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;
}

I have tried to realloc inside the first for loop, but it wasn't working even if it makes sense to have it there. 我尝试在第一个for循环内重新分配,但是即使在那里有意义也没有用。 Have also tried to convert the loop to a while loop like this: 还尝试过将循环转换为while循环,如下所示:

     while(input != "stop)
    {
      allocate more memory
}

How can I use realloc to in order to skip having to enter the persons number before entering them? 我如何使用realloc来跳过在输入人员编号之前必须输入的编号?

realloc is the correct way. realloc是正确的方法。 Just start with Ptr = NULL and num = 0 and on each input increase the number of elements by one. 只需从Ptr = NULLnum = 0开始,然后在每个输入上将元素数增加一。

Remember to limit the number of characters scanf can read, otherwise you may buffer overrun. 切记限制scanf可以读取的字符数,否则可能会缓冲溢出。

Also I find Ptr[i] way easier then (Ptr+i)-> . 我也发现Ptr[i] (Ptr+i)->更容易。

Also compare strings with strcmp not using != . 还要比较不使用!= strcmp字符串。 The != will compare pointers to strings, not strings themselves. !=将比较指向字符串的指针,而不是字符串本身。

As I like reading the whole line, then scanning the line, I would do it like this: 当我喜欢阅读整行,然后扫描该行时,我会这样做:

#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;
}

If you are not sure of the no.of.elements you want to allocate and do it based on the users choice, then you can follow the below approach. 如果不确定要分配的元素数量并根据用户选择进行分配,则可以采用以下方法。

It starts with one element and the memory is reallocated as when the user wants to add new element. 它从一个元素开始,并且在用户想要添加新元素时重新分配内存。

#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;
}

You should use a data struct like vector . 您应该使用像vector这样的数据结构。

  1. vector_init init vector. vector_init初始化向量。
  2. vector_push push val to vector , if necessary, will realloc memory. vector_pushvalvector ,如果需要的话,将realloc存储器。
  3. vector_output output the vector . vector_output输出vector

The following code could work: 以下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;
}

To answer exactly, you can first read the input to temp variables and check if you need to stop: Break the loop if so. 为了准确回答,您可以先读取temp变量的输入,然后检查是否需要停止:如果需要,则中断循环。 Or continue and reallocate the 'storage' array by increasing it's size by one and copying the values you just read to the 'storage' array. 或者继续,通过将“存储”数组的大小增加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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM