0

I am making a Book Management application, in which I take books the user puts in and save it in struct Books. The problem I am running into however is that sprintf() doesn't wanna take any of the values from my struct and instead throws an Address boundary error

The output should be this:

{
ID:1
TITLE:whatever the title is
AUTHOR:Same here
DESCRIPTION:What a surprise, it's the same
}

main.c:


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

int main(int argc, char * argv[]) {
    struct Config cfg;
    cfg.valuesSize = 0;
    struct Books books;

    // This throws Frontend screens at the user
    // While also pipelining to backend functions
    while(true) {
        // Was a screen, but made easier for people to debug
        int welcome = 2;
        switch (welcome) {
            case 2: {
                struct Books anotherBook = addBookScreen();
                anotherBook.id = cfg.valuesSize;
                books.next = &anotherBook;
                anotherBook.prev = &books;

                /*
                    What's odd is that I am able
                    to get the value of anotherBook.name
                    here, but I can't get it
                    in the sprintf at all
                */
                printf("%d", anotherBook.id+1);

                char cfgInfo[400];

                // This line causes an Address boundary error
                sprintf("{\nID:%d\nTITLE:%s\nAUTHOR:%s\nDESCRIPTION:%s\n}", 
                         anotherBook.id, anotherBook.name, anotherBook.author, 
                         anotherBook.description);

                printf("%s", cfgInfo);

                // Not calling due to incorrect cfgInfo
                //read_config(cfg, cfgIn);
                continue;
            }
            default: {
                continue;
            }
        }
        break;
    }

    update_config("test-cfg.cfg", cfg);
    free(cfg.values);
    return 0;
}

screens.c

struct Books addBookScreen() {
    struct Books book;

    printf("Enter name of book: ");
    char name[60];
    scanf("%s", name);
    book.name = name;
    
    printf("\nEnter Author: ");
    char author[100];
    scanf("%s", author);
    book.author = author;

    printf("\nEnter Description: ");
    char description[240];
    scanf("%s", description);
    book.description = description;

    return book;
}

books.h

struct Books {
    int id;
    char * name;
    char * author;
    char * description;

    struct Books * next;
    struct Books * prev;
};
Primitive
  • 91
  • 1
  • 6
  • 4
    The `addBookScreen` function have arrays for the strings. These arrays are local variables inside the function, and as such their life-time will end immediately when the function returns. You save pointers to these arrays, and those pointers will become invalid. Dereferencing the pointers, like what happens when you print the, as strings, will lead to *undefined behavior*. Easy solution: Make the structure strings *arrays* instead, and read directly into them with `scanf` (or better yet `fgets`). – Some programmer dude Apr 04 '22 at 18:45
  • 1
    Plus the first argument to `sprintf` should be a buffer to write the formatted data to and the _second_ argument the format string, followed by the data items. Violating this is _also_ UB, and for a literal format string (as you have) this UB is more likely (though not required) to be detected as it apparently was. Given your program sequence you probably wanted `sprintf (cfgInfo, "{\nblah%stuff\n}", ...)`. – dave_thompson_085 Apr 04 '22 at 19:24

0 Answers0