Reputation: 262
Here are my two structs:
typedef struct simple_command_t {
char * in, *out, *err;
char **tokens;
int builtin;
} simple_command;
typedef struct command_t {
struct command_t *cmd1, *cmd2;
simple_command* scmd;
char oper[2];
} command;
And here is the code I'm using:
int main() {
command *check1;
if ((check1 -> scmd -> tokens) == NULL){
printf("tokens are null");
}
return 0;
}
Since I've read that you can't check if a struct is NULL
I've tried checking the members inside of the empty struct instead. Unfortunately everything I've tried so far has been giving me segfaults. What's the problem?
Upvotes: 0
Views: 239
Reputation: 263647
There is no such thing as an "empty" struct. (The phrase "empty struct" would make sense if C permitted structs with no members, but it doesn't, and that's not what you're referring to anyway.)
I think what you're trying to do is check whether the struct has been initialized, either via an initializer or an assignment. There is no way to do that.
Here's a simpler example:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *ptr;
/* code that may or may not initialize ptr */
if (<ptr has been initialized>) {
printf("ptr = %p, *ptr = %d\n", (void*)ptr, *ptr);
}
else {
fprintf(stderr, "ptr is uninitialized\n");
exit(EXIT_FAILURE);
}
}
There is no way to write the condition <ptr has been initialized>
. Since ptr
is not a static
object, its initial value is not necessarily a null pointer or any other particular value; it is indeterminate garbage. It could, just by coincidence, happen to contain a valid address; there is no way to distinguish between that possibility and an actual valid value that was stored in ptr
deliberately.
The only reliable way to determine whether ptr
has been initialized or not is to initialize it:
int *ptr = NULL;
The same reasoning applies to your example. You define a pointer object:
command *check1;
It's defined in side a function, it's not static
, so its initial value is indeterminate garbage. Just reading the value of the pointer:
if (check1 == NULL) ...
has undefined behavior; even if it didn't, the result of the comparison wouldn't tell you anything useful. You must carefully write your code so that you never attempt to use the value of check1
before assigning a known value to it. The easiest way to do that is simply to initialize it:
command *check1 = NULL;
If you initialize it to NULL
it doesn't point to anything; there is no structure object to test. You can create a structure and assign its address to check1
:
check1 = malloc(sizeof *check1);
Now check1
has a valid value (which could still be a null pointer of malloc
failed; always check for that). If malloc
succeeded, check1
points to a struct object whose value itself is indeterminate garbage. The same considerations that applied to check1
itself now apply to the struct object *check1
, and to each of its members.
One common approach is to define a function that creates a struct object and properly initializes all its members.
Upvotes: 4