在结构内为结构数组分配内存

时间:2018-08-05 16:55:11

标签: c data-structures

我有一个要工作的应用程序,在这里我需要使用结构类型的数组作为structure的成员。我已经创建了具有结构的模型,但是正如您所看到的,我需要一个作为接触结构内部数组的成员(动态地取决于用户的输入)。我正在通过从main传递一个名为contactPersonLength的变量来在getContacts函数中为其分配大小,但是一旦getContacts返回到contactPersonLength的主值时,变量就会更改,并且垃圾值会在main中打印。所以我在传递变量到打印功能时遇到了麻烦。请告诉我我错了,以及如何为结构成员的数组分配大小

struct address
{
    char *name,*street,*district;
    int doorNo;
};

struct contactPerson
{
    char *name,*contactNumber;
};

struct contact
{
    char *firstName,*lastName,*emailId;
    struct address billingAddress;
    struct address shippingAddress;
    struct contactPerson contactPersons[];
};

void getContacts(struct contact *contacts,int n,int contactPersonLength)
{
    int isSame,i,j;
    for(i=0;i<n;i++)
    {
        printf(".......Enter Contact Details %d  ........\n",i+1);
        contacts[i].firstName = (char *)malloc(sizeof(char));
        printf("Enter the First Name");
        scanf("%s",contacts[i].firstName);

        contacts[i].lastName = (char *)malloc(sizeof(char));
        printf("Enter the Last Name");
        scanf("%s",contacts[i].lastName);

        contacts[i].emailId = (char *)malloc(sizeof(char));
        printf("Enter the email id");
        scanf("%s",contacts[i].emailId);

        printf(".....Billing address Details.....\n");
        contacts[i].billingAddress.name = (char *)malloc(sizeof(char));
        printf("Enter the name");
        scanf("%s",contacts[i].billingAddress.name);

        printf("Enter the DoorNo");
        scanf("%d",&contacts[i].billingAddress.doorNo);

        contacts[i].billingAddress.street = (char *)malloc(sizeof(char));
        printf("Enter the Street name");
        scanf("%s",contacts[i].billingAddress.street);


        contacts[i].billingAddress.district = (char *)malloc(sizeof(char));
        printf("Enter the District");
        scanf("%s",contacts[i].billingAddress.district);

        printf(".....Shipping Address Details....\n");
        printf("Is your Shipping Address same as Billing Address Press 1 Or else Press 0");
        scanf("%d",&isSame);
        if(isSame==1)
        {
            contacts[i].shippingAddress = contacts[i].billingAddress;
        }
        else
        {
            contacts[i].shippingAddress.name = (char *)malloc(sizeof(char));
            printf("Enter the name");
            scanf("%s",contacts[i].shippingAddress.name);

            printf("Enter the DoorNo");
            scanf("%d",&contacts[i].shippingAddress.doorNo);

            contacts[i].shippingAddress.street = (char *)malloc(sizeof(char));
            printf("Enter the Street name");
            scanf("%s",contacts[i].shippingAddress.street);

            contacts[i].shippingAddress.district = (char *)malloc(sizeof(char));
            printf("Enter the District");
            scanf("%s",contacts[i].shippingAddress.district);
        }

        printf(" ContactPersonLength %d \n",contactPersonLength);
        contacts[i].contactPersons[contactPersonLength];
        for(j=0;j<contactPersonLength;j++)
        {
            printf(".....ContactPerson %d.....\n",j+1);
            contacts[i].contactPersons[j].name = (char *)malloc(sizeof(char));
            printf("Enter Contact Person Name");
            scanf("%s",contacts[i].contactPersons[j].name);

            contacts[i].contactPersons[j].contactNumber = (char *)malloc(sizeof(char));
            printf("Enter Contact Person Contact Number");
            scanf("%s",contacts[i].contactPersons[j].contactNumber);
        }
    }

}



void main()
{   
    struct contact contacts[n];

    getContacts(contacts,n,contactPersonLen);
}

2 个答案:

答案 0 :(得分:3)

我建议您使用以下功能:

char buffer[256];
for(i=0;i<n;i++)
{
    printf(".......Enter Contact Details %d  ........\n",i+1);
    do {
        printf("Enter the First Name");
    } while (scanf("%255s",buffer)!=1);
    contacts[i].firstName = malloc(strlen(buffer)+1);
    strcpy(contacts[i].firstName, buffer);
    //...etc

因此,您使用单个缓冲区来获取输入,然后完全按照输入的大小分配内存,再加上一个终止的空字符,然后将缓冲区复制到该内存并将缓冲区重新用于下一个输入。

注意:char的大小始终为1,因此不需要sizeof(char)。另外,不应强制转换malloc的结果。

您在do...while循环中询问输入,并检查scanf是否能够读取输入。在scanf中,格式说明符将输入限制为255个字符,因此缓冲区不会溢出。

答案 1 :(得分:0)

(char *)malloc(sizeof(char));仅分配一个字节的内存。如果要存储一个字符串,例如20个字符长,则代码为: (char *)malloc(sizeof(char) * 20 + 1); //explicitly showed +1 for clarity, based on comment.


编辑

通常,最好在malloc中设置数组的最大可能大小。但是,如果大小太大,和/或您担心内存,请执行以下操作:

contacts[i].firstName = (char *)malloc(sizeof(char) * MAX_POSSIBLE_SIZE);
printf("Enter the First Name");
scanf("%s",contacts[i].firstName);
char *temp = (char *)realloc(contacts[i].firstName, strlen(contacts[i].firstName) + 1);
if(temp!=NULL)  contacts[i].firstName = temp;

对每个字符串执行此操作。