1

I am trying to read from keyboard and store the info in my struct book. The user is asked to enter the array size and I dynamically allocate the size to my book array. But when n > 1, the run time error is exc_bad_access. I don't know why it works when n = 1 and it doesn't work when n > 1.

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

struct book
{
    char *title;
    char *author;
    double price;
};

int main()
{
    int n, i = 0;
    printf("please enter the value for n\n");
    scanf("%d", &n);

    struct book *stack = malloc(sizeof(struct book) * n);
    stack->author = malloc(sizeof(char) * 100);
    stack->title = malloc(sizeof(char) * 100);
    //allocate memory for book and struct members
    while (i < n )
    {
        printf("Please enter the title\n");
        scanf("%s", stack[i].title);
        printf("Please enter the author\n");
        scanf("%s", stack[i].author);
        printf("Please enter the price\n");
        scanf("%lf", &stack[i].price);
        i ++;
    }
    free(stack);
    return 0;
}
4
  • sizeof (char) is redundant as it's 1 per definition. Commented Nov 2, 2014 at 11:33
  • My thought here is be able to set the upper limit for the input in terms of char number, so I think it is necessary to keep it in place right? Commented Nov 2, 2014 at 11:53
  • use a length specifier with %s to prevent buffer overflow. Also you may need to reconsider the choice of input method if there are any books with multiple words in their title or author name! Commented Nov 2, 2014 at 12:17
  • sizeof (char) * 100 equals 1 * 100 equals 100. So what is the need for using sizeof (char)? Coding 100 would do the job. Commented Nov 3, 2014 at 11:28

3 Answers 3

3

You're allocating enough structures for any size of elements you input, but not the space for the buffers:

struct book *stack = malloc(sizeof(struct book) * n);
stack->author = malloc(sizeof(char) * 100);
stack->title = malloc(sizeof(char) * 100);
// what about stack[1].author, stack[2].author and the rest??

This will work instead:

struct book *stack = malloc(sizeof(struct book) * n);
for (int i = 0; i < n; ++i) {
    stack[i].author = malloc(sizeof(char) * 100);
    stack[i].title = malloc(sizeof(char) * 100);
}

And remember to free your memory as well.

Sign up to request clarification or add additional context in comments.

1 Comment

In C casting the result of malloc/calloc/realloc isn't necessary nor is it recommended. Just do not do this.
2

For each book in the stack, you have to allocate memory for the author and the title.

for(int i = 0; i < n; i++)
{
    stack[i].author = malloc(sizeof(char) * 100);
    stack[i].title = malloc(sizeof(char) * 100);
}

You are only allocating memory for the first element.

1 Comment

stack->author = malloc(sizeof(char) * 100); stack->title = malloc(sizeof(char) * 100);
0

You need to allocate memory for

char *title;
char *author;  

When you do struct book *stack = malloc(sizeof(struct book) * n); memory is allocated for char* pointers (4 or 8 bytes depending on platform you're building).

So you need to allocate some memory for inside values

while (i < n )
{
    char *title = malloc(255 * sizeof(char));
    printf("Please enter the title\n");
    scanf("%s", title);
    stack[i].title = title;
    .....
    i ++;
}

1 Comment

Why the intermediate title? Why not allocated to and read into the struct's member directly?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.