4

I'm just getting started to learn C language by creating small programs.

Now, I'm in the middle of creating a program that require either struct or something global, because later on somewhere in my function I just want to call them directly.

I prefer not to use struct because I'm afraid that it will increase the chance of seg. fault somewhere between lines of code.

My question is: Are these two the same?

struct myTrialStruct{
    char *trialOne;
    char *trialTwo;
    char *trialThree;
};

and

extern char *trialOne;
extern char *trialTwo;
extern char *trialThree;

char *trialOne;
char *trialTwo;
char *trialThree;

If not, can somebody tell me the proper way to create a global char pointer without having me to create a struct?

John
  • 129
  • 9
  • They aren't the same; one's a `struct` and the other three are not. And using structures does not lead to segfaults per se — misuse of structures can do that, but you can get segfaults from simple char pointers too. Your naming suggests you need an array. In a single source file, you only need `static char *trialOne;` — nothing else will use it. In multiple files, you'll need a header declaring `extern char *trialOne;`, and in one file, you'll have `char *trialOne = 0;` (if you're sensible; `char *trialOne;` also works, but is more likely to lead to trouble with the One Definition Rule). – Jonathan Leffler Oct 29 '15 at 23:12
  • 2
    `struct` will not increase the chance of seg. fault, global variable does. – Bryan Chen Oct 29 '15 at 23:13
  • There's an extremely detailed (and extensive) answer to [How do I use `extern` to share variables between source files in C](https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files-in-c/); you will want to stop reading at the first, or no later than the second, point where you're invited to stop reading. – Jonathan Leffler Oct 29 '15 at 23:14
  • @JonathanLeffler I only have one file, so I think I can either use `static char *trialOne` or the `struct` that I mentioned above right? Also, thank you for the link, luckily in this small program I'm only need to dealing with one file. – John Oct 29 '15 at 23:19
  • @BryanChen so is that mean if I use `char *trialOne`, there is more chance to get seg.fault? – John Oct 29 '15 at 23:19
  • 1
    If you really must make data accessible globally, putting it all into a struct is the far better way to go, because then it becomes conceptually a single global variable rather than a mess of them. And there's nothing about structures that encourages segfaults--that's plain nonsense. – Lee Daniel Crocker Oct 29 '15 at 23:20
  • @LeeDanielCrocker got it. But then I still need function to deallocate right if I use struct? – John Oct 29 '15 at 23:22
  • If your structure contains pointers that you want to point to something (like strings), then yes, you'll have to allocate memory for them and free them when you're done. No differently than if they were outside a structure. And Bryan's right--your naming suggest you really want an array. – Lee Daniel Crocker Oct 29 '15 at 23:25
  • @LeeDanielCrocker Okay I understand now. Thank you. – John Oct 29 '15 at 23:26

2 Answers2

4

You should use a struct, if the variables make up an object. If they do:

struct myTrialStruct{
    char *trialOne;
    char *trialTwo;
    char *trialThree;
} myGlobalVar;

Just write this at the top of your source file. myGlobalVar is a global variable of type struct myTrialStruct.

Or if the three variables are part of a sequence use an array:

char *myGlobalArr[3];  // array of char *

Using a struct won't increase the chance of segfault; careless pointers will.

And try to limit the use of global variables. Your code will become very disorganized, and it will be harder to fix bugs.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
  • They are not part of the sequence, they are just there simply to provide me if I need to store something instantly. Is my way of thinking correct tho? – John Oct 29 '15 at 23:20
  • Given the names, an array might be appropriate, too. – Jonathan Leffler Oct 29 '15 at 23:20
  • 2
    @John: what? No! Do not create global variables on a whim just in case. Create global variables _only_ when there is a solid reason why the variable must exist. You should use a variable that's local to the function, or perhaps a function argument, whenever you can. Global variables lead to trouble — avoid them whenever possible. – Jonathan Leffler Oct 29 '15 at 23:25
  • @JonathanLeffler Okay I understand now. Thank you. – John Oct 29 '15 at 23:26
4

If you have one compilation unit then it is enough to place these declarations outside any function.

char *trialOne;
char *trialTwo;
char *trialThree;

If you are going to have several compilation units that will access these pointers then you should to place these declarations in a header

extern char *trialOne;
extern char *trialTwo;
extern char *trialThree;

and in some module to place these definitions of the pointers

char *trialOne;
char *trialTwo;
char *trialThree;

The header should be included in any compilation unit that need to access these pointers.

As for your question

Are these two the same?

then these

struct myTrialStruct{
    char *trialOne;
    char *trialTwo;
    char *trialThree;
};

a type declaration that is it is a structure declaration, no object is created.

while these are object declarations

char *trialOne;
char *trialTwo;
char *trialThree;

You could define an object of the structure type for example the folloiwng way

struct myTrialStruct{
    char *trialOne;
    char *trialTwo;
    char *trialThree;
};

struct myTrialStruct hlobal_pointers;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Since I'm dealing with one file only, I guess it is safe to declare the three of char pointer right? – John Oct 29 '15 at 23:21
  • 1
    Since you have only one file, no need to use `extern`. – lost_in_the_source Oct 29 '15 at 23:21
  • @John You are right. Simply declare them (without specifier extern) before main. – Vlad from Moscow Oct 29 '15 at 23:22
  • Okay that's cool. Do I also need to deallocate them too at the really end of the code? – John Oct 29 '15 at 23:24
  • 1
    @John If you will allocate memory yourself using standard C functions malloc or calloc then you need to call function free to free the allocated memory. For example trialOne = malloc( 6 ); strcpy( trialOne, "Hello" ); /*.*/ free( trialOne ); – Vlad from Moscow Oct 29 '15 at 23:26
  • 1
    You can't 'deallocate' the global variables. However, since you have `char *trialOne` etc, you might have used dynamic memory allocation to allocate the space they point at. In that case, it is good practice to release the memory before exiting, but it is not crucial (modern OS automatically release the memory when the program exits; old OS — the original AmigaOS for example — did not, but that is now archaic). It is crucial that you know how the memory was allocated, because it is not safe to release all `char *` variables; the value must have been returned by `malloc()` or its colleagues. – Jonathan Leffler Oct 29 '15 at 23:29