Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    2

    Pointer to struct help please ??


    I wrote a program(WITH NO SYNTAX ERROR AND NO WARNING AT ALL but still crashes) which awaits user's input for a book struct. The struct is this:

    typedef struct
    {
    char *book_name;
    char *author_name;
    char *name_of_publisher;
    int year_of_publishing;
    float cost;
    int serial_number;
    }Book;

    I created an array of pointer to the struct:

    Book *array[2];

    And from main, inside a loop, i call to the function which inputs the book data, like this:

    input_book(array[i]); (here i pass the pointer to the struct)

    But once it gets to the function for data input the program just gets stuck and i have to close it.

    It starts like this:

    void input_book(Book *pbook)
    {

    String temp; (String is a defined array)
    scanf("%s", temp);
    pbook->book_name=strdup(temp);
    .....
    ....
    ....
    }

    Does anyone have an idea why the program won't run properly? There are no warnings from the compiler.
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    What compiler? What IDE? How are you ensuring that warnings get displayed? I've seen some IDEs (eg, Dev-C++) that don't display warnings even when you've turned them on. And just this morning I dealt with a post here where the OP insisted that he got no warnings and yet when I compiled it I got a lot of warnings, including ones that pointed to the reason for his program crashing. So how do you know for a fact that your program does not throw warnings?

    Code listing, please. You aren't giving us enough information to work with. If the entire code is too big, then create a smaller test program with your input_book function in it and that will compile and post that.

    With a code listing, we can see the rest of the function, which will probably show us the problem. Also, we will be able to compile it ourselves, thus verifying the reported lack of warnings, and try to run it ourselves. It will give us something to work with instead of having to play guessing games.
    Last edited by dwise1_aol; July 30th, 2013 at 11:49 AM.
  4. #3
  5. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,376
    Rep Power
    1871
    Book *array[2];

    And from main, inside a loop, i call to the function which inputs the book data, like this:

    input_book(array[i]); (here i pass the pointer to the struct)
    And does i have values other than 0 or 1, which are the only valid subscripts for your small array.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    2
    Originally Posted by salem
    And does i have values other than 0 or 1, which are the only valid subscripts for your small array.
    No, for debugging i left only 2 rows. But still can't figure it out...
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    Code listing, please!

    We don't have time to waste playing guessing games with you!

    PS

    Plus the input data you're typing in. And an explanation of how you are handling the presence of spaces within the "book name" that you enter. That means that you need to describe precisely what you are typing in.

    PPS

    The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.

    Brian W. Kernighan, in the paper Unix for Beginners (1979)
    (my emphasis added)
    What do you get when you insert printf's after each scanf that reports both what got read in and whether the scanf succeeded? I trust that you are aware of the return value of scanf and what it means. If you are not aware of scanf's return value, then why use a function that you don't know anything about?

    And if you have not yet bothered to inspect what scanf is reading in, then why not? That is the first step in the process of debugging!
    Last edited by dwise1_aol; July 30th, 2013 at 03:44 PM.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    2
    Sorry, that's the code:

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

    typedef char *String;

    typedef struct
    {
    char *book_name;
    char *author_name;
    char *name_of_publisher;
    int year_of_publishing;
    float cost;
    int serial_number;
    }Book;


    void input_book(Book *pbook)
    {

    char c;
    String temp;
    scanf("%s", temp);
    scanf("%c", c); /*For the newline character */
    pbook->book_name=strdup(temp);
    scanf("%s", temp);
    pbook->author_name=strdup(temp);
    scanf("%s", temp);
    pbook->name_of_publisher=strdup(temp);
    scanf("%d", &pbook->year_of_publishing);
    scanf("%c", &c); /*For the newline character */
    scanf("%f", &pbook->cost);
    scanf("%c", &c); /*For the newline character */
    scanf("%d", &pbook->serial_number);
    scanf("%c", &c); /*For the newline character */
    }


    void output_book(Book *pbook)
    {
    printf("\n\nBook name: %s\n", pbook->book_name);
    printf("Author name: %s\n", pbook->author_name);
    printf("Name of publisher: %s\n", pbook->name_of_publisher);
    printf("Year of publishing: %d\n", pbook->year_of_publishing);
    printf("Cost: %f\n", pbook->cost);
    printf("Serial number: %d\n", pbook->serial_number);
    }

    int main()
    {

    enum{ARRAY_SIZE=2};
    Book *array[ARRAY_SIZE];

    //(?)array[0]=malloc(sizeof(Book));
    //(?)array[1]=malloc(sizeof(Book));

    int i;
    for(i=0;i<ARRAY_SIZE;++i)
    {
    printf("\n\nEnter details of book number %d--book name, author name, name of publisher, year of publishing, cost of book and serial number- all seperated by newlines: \n\n", i+1);
    input_book(array[i]);
    }


    for(i=0;i<ARRAY_SIZE;++i)
    {
    printf("\n\nDetails of book number %d: \n\n", i+1);
    output_book(array[i]);
    }


    getch();
    return 0;
    }


    The compiler is Dev c\c++.

    I'm entereing the data that the input_book function requires, EACH SPERATED BY NEWLINE. I used gets() at first and changed to scanf because i've read that gets can be dangerous. Didn't change anything.

    I've entered a printf() before the first scanf in the input function, and it printed fine. But after that it awaits an input AND AFTER THE FIRST ARRAY I ENTER + NEWLINE, IT CRASHES.

    So basically it crashes after the first scanf.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    159
    Rep Power
    19
    Please use code tags when posting code.

    Where do you allocate memory for your pointers. Remember String is a pointer that needs to have memory allocated to it before you can use it with scanf().

    Jim
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    Originally Posted by jimblumberg
    Where do you allocate memory for your pointers. Remember String is a pointer that needs to have memory allocated to it before you can use it with scanf().
    He's using strdup():
    Originally Posted by man page
    The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3).
    Admittedly, I also have not used strdup() much, if at all, so I had to stop and think twice when I read that at first.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    2
    strdup= malloc+strcpy.

    I thought this should do the job of allocating.

    Sorry for the messy code, haven't mastered the code editing yet.

    I just typed in: temp=malloc(80);

    But allocating for temp didn't chage anything and it still crashes.
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    Originally Posted by C_learner
    I wrote a program(WITH NO SYNTAX ERROR AND NO WARNING AT ALL but still crashes)

    . . .

    There are no warnings from the compiler.
    Completely and utter false!
    C:TEST>gcc -Wall lerner.c
    lerner.c: In function `input_book':
    lerner.c:23: warning: format argument is not a pointer (arg 2)
    lerner.c: In function `main':
    lerner.c:72: warning: implicit declaration of function `getch'

    C:TEST>
    Here is line 23: scanf("%c", c); /*For the newline character */

    c is a char, not a char pointer. I believe that scanf is trying to use the garbage value in c as a pointer. As I explained to Kuiva this morning, since the value in c is less than 256, that should place it in the operating system's Interrupt Vector Table, a region of memory which is strengst verboten to mere users and so your program would quite rightfully be terminated immediately with extreme prejudice.

    The other warning about getch is because you did not #include its header file. Correct that deficiency!


    Use code tags!

    [code] <insert your formatted code here> [/code]

    This is what your code looks like with code tags (original formatting retrieved via the Reply button):
    Code:
    #include<stdio.h>
    #include<string.h>
    
    typedef char *String;
    
    typedef struct
    {
        char *book_name;
        char *author_name;
        char *name_of_publisher;
        int year_of_publishing;
        float cost;
        int serial_number;
    }Book;
    
    
    void input_book(Book *pbook)
    {
         
         char c;
         String temp;
         scanf("%s", temp);
         scanf("%c", c);  /*For the newline character */
         pbook->book_name=strdup(temp);
         scanf("%s", temp);
         pbook->author_name=strdup(temp);
         scanf("%s", temp);
         pbook->name_of_publisher=strdup(temp);
         scanf("%d", &pbook->year_of_publishing);
         scanf("%c", &c); /*For the newline character */
         scanf("%f", &pbook->cost);
         scanf("%c", &c); /*For the newline character */
         scanf("%d", &pbook->serial_number);
         scanf("%c", &c);  /*For the newline character */
    }   
    
    
    void output_book(Book *pbook)
    {
        printf("\n\nBook name: %s\n", pbook->book_name);
        printf("Author name: %s\n", pbook->author_name);
        printf("Name of publisher: %s\n", pbook->name_of_publisher);
        printf("Year of publishing: %d\n", pbook->year_of_publishing);
        printf("Cost: %f\n", pbook->cost);
        printf("Serial number: %d\n", pbook->serial_number); 
    }                   
    
    int main()
    {
            
        enum{ARRAY_SIZE=2};
        Book *array[ARRAY_SIZE];
        
        //(?)array[0]=malloc(sizeof(Book));
        //(?)array[1]=malloc(sizeof(Book));
        
        int i;
        for(i=0;i<ARRAY_SIZE;++i)
        {
            printf("\n\nEnter details of book number %d--book name, author name, name of publisher, year of publishing, cost of book and serial number- all seperated by newlines: \n\n", i+1);
            input_book(array[i]);
        }
    
        
        for(i=0;i<ARRAY_SIZE;++i)
        {
            printf("\n\nDetails of book number %d: \n\n", i+1);
            output_book(array[i]);
        } 
        
       
    getch();
    return 0;
    }
    See the difference that it makes? Use code tags.

    Comments on this post

    • salem agrees
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    2
    I just removed all the scanfs for %c and left only a gets(temp); at the end of the function, to read up to the end of the line.

    And now it lets me enter all the details of book1, then goes to the second one- lets me enter the VERY FIRST string. Then i press ENTER and it CRASHES AGAIN.

    Code:
    Replaced scanfs with gets() just in case.
    
    String temp;
         temp=malloc(80);
         gets(temp);
         pbook->book_name=strdup(temp);
         gets(temp);
         pbook->author_name=strdup(temp);
         gets(temp);
         pbook->name_of_publisher=strdup(temp);
         scanf("%d", &pbook->year_of_publishing);
         scanf("%f", &pbook->cost);
         scanf("%d", &pbook->serial_number);
         gets(temp);
    Maybe it's something to do with the fact that the function is being called within a loop ?
  22. #12
  23. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    What happened when you simply replaced
    scanf("%c", c);
    with
    scanf("%c", &c);
    ? You should always try the simplest fix first.

    However, I missed the big problem in your code:
    Code:
    typedef char *String;
    
     . . . 
    
         String temp;
    In the code that you posted, you never allocated any memory to temp, so you were using an unintialized pointer which points to a garbage location. But now you seem to be saying that you've added a malloc back in.

    Please post the current version of input_book(). And also post the input data that you are using. Exactly, character-for-character, as you are inputting it! Do not withhold necessary information from us!

    That code had better contain debugging print statements and be testing the return values of the scanfs!
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    2
    Originally Posted by dwise1_aol
    What happened when you simply replaced
    scanf("%c", c);
    with
    scanf("%c", &c);
    ? You should always try the simplest fix first.

    However, I missed the big problem in your code:
    Code:
    typedef char *String;
    
     . . . 
    
         String temp;
    In the code that you posted, you never allocated any memory to temp, so you were using an unintialized pointer which points to a garbage location. But now you seem to be saying that you've added a malloc back in.

    Please post the current version of input_book(). And also post the input data that you are using. Exactly, character-for-character, as you are inputting it! Do not withhold necessary information from us!

    That code had better contain debugging print statements and be testing the return values of the scanfs!
    I replaced the scanf with gets for the simplicity (still crashed).

    Code:
    void input_book(Book *pbook)
    {
         
         
         String temp;
         temp=malloc(80);
         gets(temp);
         puts("hello world");
         pbook->book_name=strdup(temp);
         gets(temp);
         pbook->author_name=strdup(temp);
         gets(temp);
         pbook->name_of_publisher=strdup(temp);
         scanf("%d", &pbook->year_of_publishing);
         scanf("%f", &pbook->cost);
         scanf("%d", &pbook->serial_number);
         gets(temp);
         free(temp); /*Adding this DID NOT HELP */
    }
    Input in the first loop:

    "Harry Potter"
    "\n"
    -----now---->------"hello world" is printed for DEBUG
    "J.K."
    "\n"
    "good morning"
    "\n"
    "123"
    "\n"
    "123"
    "\n"
    "123"
    "\n"

    NEXT LOOP STARTS with

    Input:

    "Harry Potter"
    "\n"
    -----now---->------"hello world" is printed for DEBUG

    And right after "hello world" is printed he craches (WITHOUT me having to press anything).
  26. #14
  27. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    What kind of debugging is that? Next to useless!
    Code:
    void input_book(Book *pbook, int a)
    {
         
         int  iResult;     // for scanf return values
         String temp;
         temp=malloc(80);
         printf("Enter Book Name: ");    // not for debugging, but a prompt 
                                        //  that also tells you where in 
                                        //  the function you are
         gets(temp);
         printf("entered: %s\n", temp);  // this is a debug print
         pbook->book_name=strdup(temp);
         printf("book_name = %s\n", pbook->book_name);  // this is a debug print
         printf("Enter Author Name: ");    // prompt 
         gets(temp);
         printf("entered: %s\n", temp);  // this is a debug print
         pbook->author_name=strdup(temp);
         printf("author_name = %s\n", pbook->author_name);  // this is a debug print
         printf("Enter Publisher Name: ");    // prompt 
         gets(temp);
         printf("entered: %s\n", temp);  // this is a debug print
         pbook->name_of_publisher=strdup(temp);
         printf("name_of_publisher = %s\n", pbook->name_of_publisher);  // this is a debug print
         printf("Enter Year of Publishing: ");    // prompt 
         iResult = scanf("%d", &pbook->year_of_publishing);
         printf("%d conversions; year_of_publishing = %d\n", iResult, pbook->year_of_publishing);
         printf("Enter Cost: ");    // prompt 
         iResult = scanf("%f", &pbook->cost);
         printf("%d conversions; cost = %f\n", iResult, pbook->cost);
         printf("Enter Serial Number: ");    // prompt 
         iResult = scanf("%d", &pbook->serial_number);
         printf("%d conversions; serial_number = %d\n", iResult, pbook->serial_number);
         gets(temp);   what the hell is this here for?
         free(temp); /*Adding this DID NOT HELP */ // BUT IT IS NECESSARY!
    }
    Each of those calls to scanf must report one conversion. If they don't, then you have a problem there, such as unexpected input.

    Do you see what those debugging print statements are doing? They echo back to you exact what was read in, plus what was stored in the struct fields. Yes, some debug statements only tell you where in the code you are, but some also need to tell you what certain values are.

    This is the poor man's way to debug without a debugger. You really need a debugger.
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    2
    I really aprreciate the debug help :)

    I've run the debug option in the compiler and after enetering the input, he stops just before the crash (the same place- second loop in the beginning), AND highlights this line in blue:

    pbook->book_name=strdup(temp);

    And gives the message: "An access violation (segmentation fault) raised in your program".

    Google says it's something to do with no allocation...but everything is allocated :confused:

    But this debug option always gives me information such as above, for which i probably need knowledge not just in C....? So i always used prints.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo