KurdTt-
KurdTt-

Reputation: 533

Adding record to structure in C

I've got structure of Books:

 typedef struct {
   int ID;
   char* Title;
 } Book;

I just want to add record to Book table. That's my function:

void AddRecord(Book**b, int *records_num){

    *records_num = *records_num + 1;

    Book* temp = (Book*)malloc(sizeof(Book) * records_num);
//FirstMethod
    memcpy(temp, *b, records_num * sizeof(Book)); //Doesn't work

    //SecondMethod
    int j;

    for(j = 0; j < records_num - 1; j++){
        temp[j] = (*b)[j];
    }

    free(*b);
    *b = temp;
//Some logic about adding a new record
}

Both methods fails after run. That's how I call this function: AddRecord(books, &number_of_lines); It doesn't work. What's wrong here?

EDIT:

I have changed some things in code. It still works bad, but gives no error.

void AddRecord(Book *b, int *records_num){

    *records_num = *records_num + 1;

    Book* temp = (Book *)malloc(sizeof(Book) * *records_num);
    memcpy(temp, b, sizeof(b));
    b = (Book *)realloc(b, sizeof(Book) * *records_num);
    memcpy(b, temp, sizeof(temp));
    b[*records_num - 1].ID = *records_num;
}

Why this code is wrong?

Upvotes: 1

Views: 2586

Answers (1)

Baltasarq
Baltasarq

Reputation: 12212

Firstly, take a look to your structure:

 typedef struct {
   int ID;
   char* Title;
 } Book;

This structure means that you do not plan to store the title of the book inside the struct, but in the heap, by means of strdup() or something. If you had planned to store the title whithin the struct, then you would have something like:

 typedef struct {
   int ID;
   char Title[100];
 } Book;

Both methods have strong and weak points. For example, the second one is more tidy using memory, but it probably wastes a lot of space.

Your code has some stars missing here and there. If you plan to have your vector modified, it is right to pass it as Book **, but then remember that in each use, you will have to put a star before its name. The same happens with num_records. Finally, when you don't have books (the first step), you should not copy or free anything.

void addRecord(Book** v, int *records_num, const Book * b)
{
    // Reserve new space and copy
    Book * temp = (Book *) malloc( sizeof(Book) * ( *records_num + 1 ) );

    if ( *v != NULL ) {
        memcpy( temp, *v, ( *records_num ) * sizeof( Book ) );
        free( *v );
    }

    *v = temp;

    // Add new book
    (*v)[ *records_num ].id = b->id;
    (*v)[ *records_num ].title = strdup( b->title );
    ++( *records_num );
}

How do you use this? By defining some books and adding them to your collection.

int main(void) {
    Book * books = NULL;
    Book b1;
    Book b2;
    Book b3;
    int num = 0;

    // Prepare books
    b1.id = 1;
    b1.title = "Moby Dick";
    b2.id = 2;
    b2.title = "War and peace";
    b3.id = 3;
    b3.title = "Anna Karenina";

    // Add them to the vector
    addRecord( &books, &num, &b1 );
    addRecord( &books, &num, &b2 );
    addRecord( &books, &num, &b3 );

    // Show all books
    showBooks( books, num );

    // Finish
    freeBooks( books, num );
    return 0;
}

Remember, anyway, that all those titles will have to be freed before the vector of books is freed. That's done in freeBooks():

void freeBooks(Book * v, int num)
{
    int i = 0;

    for(; i < num; ++i) {
        free( v[ i ].title );
    }

    free( v );
}

You can access the whole code here: http://ideone.com/mQQeKi

Hope this helps.

Upvotes: 1

Related Questions