Allocation problem when creating an array

87 Views Asked by At

I want to invite 2 people for this club, so there's a godFather who do that and he has to invite this 2, but the first one has the priority to invite another 2, and then the second one has the chance to do so. But idk why it's reading the first one but when i try to invite the second the program stops.

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

typedef struct people{
    char name[40];
    int id;
    struct people *pgodFather;
    struct people *pfirst;
    struct people *psecond;
}People;

int id = 0; // Percorrer os arrays
bool accepted;

People *peopleList; // Apontar para o primeiro
int initialSize = 10;
People **arrayPeople;

void verificationSize(){
    if(id >= initialSize){
        initialSize *= 2;
        arrayPeople = realloc(arrayPeople, initialSize * sizeof(People));
    }
}

bool verificationId(){
    int ids;

    printf("Type your ID: ");
    scanf("%d", &ids);

    if(ids == ((2*(id-1)) + 1) || ((2*(id-1)) + 2)){
        return true;
    } else{
        printf("NO PRIORITY\n");
        return false;
    }
}

void invite(){
    system("cls");
    verificationSize();
    People *p = (People*)malloc(sizeof(People));

    if(id == 0){
        p->id = 0;
        accepted = true;
    }else if(id > 0){
        accepted = verificationId();
    } else{
        printf("ID ERROR\n");
        accepted = false;
    }

    if(accepted == true){
        // arrayPeople[id] = p;
        printf("Type your name: ");
        scanf("%s", p->name);
        p->pgodFather = peopleList; // null, [0], [1],
        peopleList = p; // [0], [1], [2]

        printf("Invite the first one: ");
        scanf("%s", arrayPeople[(2*id) + 1]->name);
        printf(arrayPeople[(2*id) + 1]->name);
        p->pfirst = arrayPeople[(2*id) + 1];

        char name[40];
        printf("Invite the second one: ");
        scanf("%s", arrayPeople[(id*2)+2]->name);
        p->psecond = arrayPeople[(id*2) + 2]; // PROBLEMA
        printf(arrayPeople[(2*id) + 2]->name);
        
        id++;
    }
}

int main(void){
    arrayPeople = (People**) malloc(initialSize * sizeof(People*));
    int choice;
    bool stop = false;

    while(!stop){
        printf("CROWS CLUB\n");
        printf(" 1 - Invite\n");
        printf(" 2 - Search\n");
        printf(" 3 - Display\n");
        printf(" 4 - Delete\n");
        printf(" 5 - Exit\n");

        printf("Choose the alternative: ");
        scanf("%d", &choice);

        switch(choice){
            case 1:
                invite();
            break;

            case 2:
               // search();
            break;
            
            case 3:
                // display();
            break;

            case 4:
               // delete();
            break;

            case 5:
                stop = true;
            break;

            default:
                printf("Invalid Option");
            break;
        }
    }
    return 0;
}

// for(int f = 0; f < initialSize; f++){
//     free(arrayPeople[f]);
// }

// free(arrayPeople);

I want to invite people following this rules, i have to do it in this array

1

There are 1 best solutions below

1
MikeCAT On

You only allocated the array arrayPeople and didn't initialize its elements.
Therefore, the elements like arrayPeople[(2*id) + 1] have indeterminate values and using the values (dereferencing like arrayPeople[(2*id) + 1]->name, for example) invokes undefined behavior.
When undefined behavior is invoked, anything can happen. Your program may or may not crash on undefined behavior.

Allocate memory and assign to the elements before dereferencing.

Example (error check is omitted for simplicity):


        printf("Invite the first one: ");
        arrayPeople[(2*id) + 1] = malloc(sizeof(**arrayPeople)); // allocate memory
        scanf("%39s", arrayPeople[(2*id) + 1]->name);
        fputs(arrayPeople[(2*id) + 1]->name, stdout);
        p->pfirst = arrayPeople[(2*id) + 1];

        char name[40];
        printf("Invite the second one: ");
        arrayPeople[(id*2)+2] = malloc(sizeof(**arrayPeople)); // allocate memory
        scanf("%39s", arrayPeople[(id*2)+2]->name);
        p->psecond = arrayPeople[(id*2) + 2]; // PROBLEMA
        fputs(arrayPeople[(2*id) + 2]->name, stdout);

Also note that:

  • Casting results of malloc() family is considered as a bad practice.
  • Passing user-input strings to the 1st argument of printf is dangerous because the input may contain %s for formatting. Instead of printf(something), you should use fputs(something, stdout) or printf("%s", something).
  • Using %s with scanf is dangerous because it may read input with unlimited length and may cause buffer overrun. You should specify the maximum length to read like %39s. The maximum length has to be less than the buffer size. (the buffer size is too long to specify because then a room for the terminating null-character is not allocated)
  • The allocation in the function verificationSize is wrong. Elements of the array arrayPeople is People*, so the allocation size should be initialSize * sizeof(People*) or initialSize * sizeof(*arrayPeople), not initialSize * sizeof(People).
  • The condition ids == ((2*(id-1)) + 1) || ((2*(id-1)) + 2) in the function verificationId will always be true for all positive id small enough not to cause overflow because ((2*(id-1)) + 2) will always be positive. You may want to use ids == ((2*(id-1)) + 1) || ids == ((2*(id-1)) + 2) instead.