-2

I am trying to learn to access an array of structs. The following code compiles but seg faults (core dump) when executed. What have I done wrong?

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

// data structure
struct book {
  int     book_id;                     // book id
  int     (*ptFunc) ( struct book  );  // addr of printBook function
  char    title[50];                   // book title
  char    author[50];                  // book author
};

struct book aBooks[10];

/*************************************************************************
 *                                  main                                 *
 *************************************************************************/

void printBook ( struct book aBooks[], int id ) {
  printf ( "book_id       : %d\n", aBooks[id].book_id );  // access to struct
  printf ( "func addr     : %p\n", aBooks[id].ptFunc  );  // pointer to funcion
  printf ( "title         : %s\n", aBooks[id].title   );  // string
  printf ( "author        : %s\n", aBooks[id].author  );  // string
  printf ( "\n" );
}

int main (void) {

  strcpy ( aBooks[0].book_id,  0 );
  strcpy ( aBooks[0].ptFunc,  printBook );
  strcpy ( aBooks[0].title, "This Little Piggy" );
  strcpy ( aBooks[0].author, "Bad Wolf" );

  printBook (aBooks, 0 );                          // function to show selected data

  return 0;
}

Solution: Copy and paste got me! (I had the pointer to a function working and then added assigning a string and copy and pasted too much!) With the help of "chrslg", the assignment section should have been:

  aBooks[0].book_id =  0 ;
  aBooks[0].prtFunc = printBook;
  strcpy ( aBooks[0].title, "This Little Piggy" );
  strcpy ( aBooks[0].author, "Bad Wolf" );

[ Thanks for the help, I did not know there was a difference between "Super User" and "Stack Overflow", I learned something! ]

jwzumwalt
  • 203
  • 2
  • 11
  • Have you tried running your code line-by-line in a debugger while monitoring the control flow and the values of all variables, in order to determine in which line your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Jul 16 '23 at 10:10
  • 2
    Your compiler should provide helpful warning messages when compiling this program. – Paul Hankin Jul 16 '23 at 10:16
  • @AndreasWenzel Apparently, he forgot to add the `#` before the `include`s. Otherwise, the code compiles with multiple warnings and segfaults upon running. – Mehdi Charife Jul 16 '23 at 13:01

1 Answers1

5

strcpy ( aBooks[0].book_id, 0 );

Means copy the string that is at address 0 into the memory at address aBooks[0].book_id (so 0 too, since aBooks is a global variable, so initialized to 0).

Reading and writing address 0 leads to seg fault.

And anyway, this is not a string.

You meant aBooks[0].book_id=0

chrslg
  • 9,023
  • 5
  • 17
  • 31
  • Why does reading from address 0 leads to segfaul thought? Is it reserved for something? – Mehdi Charife Jul 16 '23 at 10:16
  • 1
    @MehdiCharife https://stackoverflow.com/questions/2960496/why-is-null-0-an-illegal-memory-location-for-an-object – Paul Hankin Jul 16 '23 at 10:20
  • 1
    Well, if there weren't any special reason associated to this specific address, any way, you can't read and write to random address. Here, obviously, address from which we read, and to which we write is 0 just because it happens to be what is in those variables that are not at all intended to be addresses. So that would be like storing a result at address 12: it is very unlikely that this number is one of the addresses that belong to your program, and where it is allowed to read/write. Addresses have to come either from `&` operator (to get the address of a real variable), or `malloc` – chrslg Jul 16 '23 at 10:20
  • 2
    He would also need to change `strcpy ( aBooks[0].ptFunc, printBook );` as both arguments are not strings, and the two have different signatures. – Mehdi Charife Jul 16 '23 at 10:21
  • 2
    @MehdiCharife But in addition to this argument (just a random number can't be a legal address, accessible by your code, or at least the probability that it is is very close to 0), there is a special reason for 0. In C, 0 is a special address that is treated as the null pointer. See link given by PaulHankin – chrslg Jul 16 '23 at 10:23
  • Yes. I made 2 comments. One saying that. The 1st one starting by "if 0 weren't a special case". – chrslg Jul 16 '23 at 12:29