Search code examples
cpointerssegmentation-faultncurses

C ncurses: Create WINDOW in another function


I am new to ncurses and very rusty on C so I assume there's a simple explanation to this. I want to have a WINDOW as a property of a struct and pass that around to other functions. But everytime I use the WINDOW outside the function, I get a segmentation fault.

test1 is my ideal but I'll do whatever works.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <ncurses.h>

struct Program {
    WINDOW *window;
};

struct Program *Program_create() {  
    struct Program p, *program = &p;
    program->window = newwin(10, 10, 0, 0);
    return program;
}

void sanity();
void test1();
void test2();
void test3();

int main(/* int argc, char *argv[]*/) {
    initscr();
    noecho();

    //sanity(); // creates box no problem
    //test1(); // Segmentation fault (core dumped)
    //test2(); // Segmentation fault (core dumped)
    //test3(); // creates box no problem

    endwin();
    return EXIT_SUCCESS/* 0 */;
}

void sanity() {
    WINDOW *window = newwin(10, 10, 0, 0);
    box(window, 0, 0);
    wrefresh(window);
    wgetch(window);
}

void test1() {
    struct Program *program = Program_create();
    box(program->window, 0, 0);
    wrefresh(program->window);
    wgetch(program->window);
}

void test2() {
    struct Program p, *program = &p;
    program = Program_create();
    box(program->window, 0, 0);
    wrefresh(program->window);
    wgetch(program->window);
}

void test3() {
    struct Program p, *program = &p;
    program->window = newwin(10, 10, 0, 0);
    box(program->window, 0, 0);
    wrefresh(program->window);
    wgetch(program->window);
}


Solution

  • struct Program *Program_create() {  
        struct Program p, *program = &p;
        program->window = newwin(10, 10, 0, 0);
        return program;
    }
    

    Reason for segmentation fault: Here, the structure instance p is a local variable. This structure instance (p) gets removed, after we return from the function. And the pointer program points to some invalid data. program becomes a dangling pointer.

    Solution : Allocate memory in heap, using malloc

    struct Program *Program_create() {  
            struct Program *program = malloc(sizeof(struct Program));
            program->window = newwin(10, 10, 0, 0);
            return program;
        }