1

I'm using global structure so I can set/get error or state from everywhere. It was working fine, now I'm in trouble.

structure

typedef struct program Program;
struct program
{
    int error;
    int state;
};

// global declarations
Program *program;

init

void init_memory(void)
{
program = malloc(sizeof(Program));
if(program == NULL)
{
    print_error(E_MEM_ALLOC);
    exit(EXIT_FAILURE);
}
program->state = S_NONE;
program->error = E_OK;
}

here program crashes, when I remove "program->error = ...." program is working fine...i don't know why :/

void check_file(char *filename)
{
FILE *file = fopen(filename, "r");

if(file == NULL)
{
    program->error = E_FILE_OPEN;
    return;
}

fclose(file);
}

whole program: http://pastebin.com/dwSVQ9x8

Arkku
  • 41,011
  • 10
  • 62
  • 84
  • What is `program`? A global variable? You're using a variable with the same name as the structure, which in turn is the same name for a `typedef`'d alias? – Filipe Gonçalves Nov 22 '13 at 11:50
  • yea I am...anyway, I tried to change variable's name and program still crashes :/ – Daniel Hladík Nov 22 '13 at 11:52
  • @FilipeGonçalves he's doing it right actually... OP: You should extern the global structure in the header file, and just define and actually allocate it in one source file, like: `extern Program* program` in the header, and in source `Program *program;` (not in same file as `check_file` in) –  Nov 22 '13 at 11:52
  • 3
    Might be silly question, but do you actually call `init_memory` before `check_file`? – user694733 Nov 22 '13 at 11:54
  • @user9000 I'd like to..but this is school project and they want to have it in one source file -_- – Daniel Hladík Nov 22 '13 at 11:55
  • @user694733 Yes, I am – Daniel Hladík Nov 22 '13 at 11:56
  • 1
    Problem seems to not be here. Show more code. – user694733 Nov 22 '13 at 11:59
  • @user9000 No doubt he's doing it right, but it in computer science it is generally good practice to use a name for one thing only. `typedef struct foo { int foo } foo; foo foo;` is valid code, but good luck debugging it. It surely is a cool trick, but not very useful, and anyone reading the code will have a hard time. – Filipe Gonçalves Nov 22 '13 at 12:00
  • 1
    @FilipeGonçalves `foo foo;` is not valid. – user694733 Nov 22 '13 at 12:01
  • @user694733 Sure it is. See http://ideone.com/wo9Vpp - and then read about C namespaces: http://stackoverflow.com/questions/3793952/understanding-c-namespaces – Filipe Gonçalves Nov 22 '13 at 12:04
  • http://pastebin.com/YDe62Vvi full code here – Daniel Hladík Nov 22 '13 at 12:07
  • @user694733 Sorry, let me rephrase that: it is valid as a local-scope variable. You can't have a global variable named `foo`, since `typedef` shares the same namespace with ordinary identifiers. My example gives the idea that `foo` is a global variable, my fault, sorry. But I can't edit it anymore. – Filipe Gonçalves Nov 22 '13 at 12:13
  • 1
    @FilipeGonçalves I was just about to post a comment saying exactly the same :) In other words, `typedef struct foo { int foo } foo foo;` is not valid, but `typedef struct foo { int foo } foo; void func(void){ foo foo;}` is. – Lundin Nov 22 '13 at 12:14
  • @FilipeGonçalves Well that's what I meant too, just kept my comment too short. Lundin put it a lot better. – user694733 Nov 22 '13 at 12:19
  • yeah, I kept mine short too :P Sorry for misunderstanding your point. – Filipe Gonçalves Nov 22 '13 at 12:20
  • I found the cause, from enum it takes only first 4 items, when I want to use 5th, program crashes..any idea why is that? – Daniel Hladík Nov 22 '13 at 12:52
  • Please don't edit your question to hide the code after you have solved the issue, others stumbling upon it in the future may still find it useful. – Arkku Nov 22 '13 at 17:30

1 Answers1

2

Making program a pointer seems unnecessary, why not just make it the actual struct:

Program program = { .error = E_OK, .state = S_NONE };

Then you don't need to worry about allocating it (and can indeed remove init_memory altogether). Just change access to its members to use . instead of ->, i.e., program.error = E_FILE_OPEN.

Arkku
  • 41,011
  • 10
  • 62
  • 84
  • (If your compiler doesn't like the designated initializers, you can also initialize it as just `Program program = { E_OK, S_NONE }`.) – Arkku Nov 22 '13 at 12:02