1

This is my code:

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

typedef struct{
    char name;
    char surname;
    int month;
    int day;
} person;

person *ptr;
int action, number_of_friends=0, a, b, day, month;
char decision;

int main(void)
{
    ptr=(person*)malloc(sizeof(person));
    while(1)
    {
        printf("Please enter the data about the person number %d\n", number_of_friends+1);
        person entered_person;
        printf("Initial of the name: "); scanf(" %c", &entered_person.name);
        printf("Initial of the surname: "); scanf(" %c", &entered_person.surname);
        printf("The day of birth: "); scanf("%d", &entered_person.day);
        printf("And the month: "); scanf("%d", &entered_person.month);
        *(ptr+number_of_friends) = entered_person;
        printf("Do you want to add more friends? (y/n) ");
        scanf(" %c", &decision);
        if (decision=='n' || decision=='N') {
            break;
        }
        number_of_friends++;
        ptr=realloc(ptr, number_of_friends);
    }
    number_of_friends++;
    person get_person;
    for (a=0; a<number_of_friends; a++)
    {
        get_person = *(ptr+a);
        printf("Person number %d\n", a+1);
        printf("Initial of the name: %c\n", get_person.name);
        printf("Initial of the surname: %c\n", get_person.surname);
        printf("The day of birth: %d\n", get_person.day);
        printf("And the month: %d\n\n", get_person.month);
    }
}

The problem is that it won't display the list of entered people correctly if the number of people is greater than... something like 5.

I believe this is connected with malloc() and realloc() (writing out-of-bounds?) but as a beginner I don't know how to solve that problem.

Defozo
  • 2,946
  • 6
  • 32
  • 51
  • malloc doesn't care about structures. it only cares about how big of a memory chunk you want. to malloc, there's no difference between `malloc(2)` and `malloc(sizeof(int))` - it'll just see an integer passed in, and try to allocate a memory block of that size. – Marc B Nov 05 '15 at 21:49
  • 3
    `ptr=realloc(ptr, number_of_friends);` -> `ptr=realloc(ptr, number_of_friends*sizeof(person));` – Eugene Sh. Nov 05 '15 at 21:50
  • Dunno why backticks are not working... – Eugene Sh. Nov 05 '15 at 21:51
  • [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Nov 05 '15 at 21:51
  • @EugeneSh. space.... – Sourav Ghosh Nov 05 '15 at 21:52
  • 1
    @SouravGhosh That's it, thanks – Eugene Sh. Nov 05 '15 at 21:52
  • Better: `other_ptr = realloc(ptr, number_of_friends * sizeof(*ptr));`. In the event that `realloc()` fails, you then have some hope to avoid a memory leak because you have not clobbered the original pointer. – John Bollinger Nov 05 '15 at 21:53
  • How do you expect the `name` and `surname` to each fit in a single char? – rici Nov 06 '15 at 05:31
  • @rici I'm about to enter only first characters of name and surname. This is a part of a simple program for IT classes. – Defozo Nov 07 '15 at 20:23
  • @defozo: fair enough. Maybe the member names could be more descriptive. – rici Nov 07 '15 at 20:32

2 Answers2

2

Your realloc() size is wrong, you want number_of_friends multiplied by the size of a person struct (I'm guessing):

ptr=realloc(ptr, number_of_friends*sizeof(person));

Edit: Also this is going to crash after the first loop:

number_of_friends++;
ptr=realloc(ptr, number_of_friends);

Since number_of_friends starts at 0

kcraigie
  • 1,252
  • 6
  • 13
1
number_of_friends++;
ptr=realloc(ptr, number_of_friends);

should be

person *tmp = realloc( ptr, sizeof *ptr * (number_of_friends + 1) );
if ( tmp )
{
  ptr = tmp;
  number_of_friends++;
}

Remember that realloc, like malloc, takes a number storage units (bytes) as an argument, not number of elements of a particular type. Also, realloc will return NULL on failure, so you want to preserve your original pointer until you're sure that the realloc operation succeeded. Similarly, you don't want to update number_of_friends until after the realloc call has completed.

John Bode
  • 119,563
  • 19
  • 122
  • 198