if( mystruct == NULL )
mystruct is not a pointer, so you cannot compare it with NULL.
You have three options:
- Add a status field to
MyStructto indicate whether the struct has been initialized correctly. - Allocate the struct on the heap and return it by pointer.
- Pass the structure as a pointer argument and return a status code (thanks @Potatoswatter).
if( mystruct == NULL )
mystruct is not a pointer, so you cannot compare it with NULL.
You have three options:
- Add a status field to
MyStructto indicate whether the struct has been initialized correctly. - Allocate the struct on the heap and return it by pointer.
- Pass the structure as a pointer argument and return a status code (thanks @Potatoswatter).
A structure is not a pointer. If you want to be able to return NULL, you're going to have to allocate the structure on the heap so you can return a pointer to it, and let the caller clean up afterwards.
That way, you can indicate failure, something like:
MyStruct *init_mystruct (void) {
MyStruct *mystruct = malloc (sizeof (*mystruct));
if (mystruct != NULL)
return NULL;
int is_ok = 1;
/* do something ... */
/* everything is OK */
if( is_ok )
return mystruct;
/* something went wrong */
free (mystruct);
return NULL;
}
int main (void) {
MyStruct *mystruct = init_mystruct();
if (mystruct == NULL) {
/* error handler */
return -1;
}
free (mystruct);
return 0;
}
There are several practical reasons why functions like fopen return pointers to instead of instances of struct types:
- You want to hide the representation of the
structtype from the user; - You're allocating an object dynamically;
- You're referring to a single instance of an object via multiple references;
In the case of types like FILE *, it's because you don't want to expose details of the type's representation to the user - a FILE * object serves as an opaque handle, and you just pass that handle to various I/O routines (and while FILE is often implemented as a struct type, it doesn't have to be).
So, you can expose an incomplete struct type in a header somewhere:
typedef struct __some_internal_stream_implementation FILE;
While you cannot declare an instance of an incomplete type, you can declare a pointer to it. So I can create a FILE * and assign to it through fopen, freopen, etc., but I can't directly manipulate the object it points to.
It's also likely that the fopen function is allocating a FILE object dynamically, using malloc or similar. In that case, it makes sense to return a pointer.
Finally, it's possible you're storing some kind of state in a struct object, and you need to make that state available in several different places. If you returned instances of the struct type, those instances would be separate objects in memory from each other, and would eventually get out of sync. By returning a pointer to a single object, everyone's referring to the same object.
There are two ways of "returning a structure." You can return a copy of the data, or you can return a reference (pointer) to it. It's generally preferred to return (and pass around in general) a pointer, for a couple of reasons.
First, copying a structure takes a lot more CPU time than copying a pointer. If this is something your code does frequently, it can cause a noticeable performance difference.
Second, no matter how many times you copy a pointer around, it's still pointing to the same structure in memory. All modifications to it will be reflected on the same structure. But if you copy the structure itself, and then make a modification, the change only shows up on that copy. Any code that holds a different copy won't see the change. Sometimes, very rarely, this is what you want, but most of the time it's not, and it can cause bugs if you get it wrong.
C++ return null struct from function - Stack Overflow
C++: Return NULL instead of struct
function cannot return null in c - Stack Overflow
c - Unable to return NULL in a function that expects an integer return type - Stack Overflow
Hello,
I am a c beginner and just thought id try writing a basic compiler.
I want to assign a struct in a function because it allows me to allocate memory much more efficiently based on the size of each element.
My code takes in a line and performs some tokenization on it and verifies syntax.
Example syntax: (I have a seperate function to remove spaces)
int(abc) = (1+a+b+Cdedf)
I want to return the entire struct in the end of the function or return NULL if something went wrong.
char varAssignment(char *line) //Lexers int/float/str declaration //CODE WORKS - JUST NEED TO PASS CHAR AND RETURN STRUCT
{
//Memory assignment
char lineCopy[strlen(line)];
strcpy(lineCopy,line);
strtok(lineCopy,"(");
int variableMemSize = strlen(strtok(NULL,")"));
strtok(NULL,"(");
int varListMemSize = strlen(strtok(NULL,")"));
struct varStruct //Struct assignment
{
char datatype[4];
char variable[variableMemSize+1];
char varList[varListMemSize+1];
};
struct varStruct varStructx;
strncpy(varStructx.datatype,strtok(line,"("),4); // Get int/flt/str prefix
if ((strcmp(varStructx.datatype,"int") != 0 && strcmp(varStructx.datatype,"flt") != 0 && strcmp(varStructx.datatype,"str")) != 0) //Did not declare int/flt/str correctly
{
printf("Datatype ERROR | Cannot accept '%s'",varStructx.datatype); //Incorrect datatype
return NULL;
}
strcpy(varStructx.variable,strtok(NULL,")")); //Get variable name
if (strcmp(strtok(NULL,"("),"=") != 0) //Did not put '='
{
printf("Syntax ERROR | Expected '%c' in assignment",'=');
return NULL;
}
strcpy(varStructx.varList,strtok(NULL,")")); //Get variable list
return varStructx; //WANT TO RETURN THIS STRUCT
}C++ objects can never be null or empty. Pointers can hold a null pointer value indicating they point at nothing.
The typical solution would be to throw an exception. Otherwise, use a pointer; just make sure you aren't returning the address of a temporary.
I wouldn't recommend trying to teach yourself C++ with knowledge from other languages, you'll hurt yourself. Grab a good beginner-level book, it's the best way to learn.
Throw an exception. That's what they're for.
Maybe there are some basic things you should rethink:
First, only pointers can be NULL, but not objects. Hence, if you return an object of type struct Stack (which is not a pointer), you cannot return NULL but just an instance of struct Stack.
Second, passing in and returning an object of struct Stack by value will result in copying the respective object; I think that passing references or pointers would be a better choice; and - if you pass in and return a pointer, you could also return NULL to indicate a full stack or some other issue.
The problem is that your function must return a value that has the type Stack.
The code you provided doesn't define the type of NULL, but, since you're not seeing another error and you're assigning it to node, I would guess that the type of NULL is StackNode *... or, at least, something compatible with that.
So, there's your problem. You're trying to return something with the type StackNode * when your function claims to return a Stack.
Your best bet is to redesign this function that returns the result of the push operation and not the Stack itself.
If the return type is int, you can't return a NULL. To show an error, you could instead return a special value like zero or -1, if you check for that value in any calling function. Lots of functions return nonnegative numbers on success, or -1 on error.
NULL cannot be stored in an int variable, unlike in SQL, for example. If you ignore the warning and return NULL anyway, then NULL will be casted to zero. The calling function won't be able to tell whether you returned NULL or zero.
If your function only needs to indicate success or failure, then it's common to return 1 for success, and zero for failure. Zero means "false" when treated as a boolean value (like in if statements), and non-zero means "true."
It looks like you've misunderstood what NULL means in C. Types are not nullable. NULL is effectively just a shorthand for the pointer with value 0! And int is not a pointer.
It seems as if the Node *head is passed by value and not by reference.
That is exactly right -- in C every parameter is always passed by value. The pointer is a value, and that value is passed by value, and the call
Insert(head, 25);
can never change the value of the variable named head. It reads the value of the variable (this value is a null pointer), gives that value to the function and never touches the variable head again no matter what the function does.
(Note that in your program you have two variables that are both named head -- one in main() and the other in Insert(). The variable in Insert() silently disappears when the function returns; nothing will automatically try to copy its value to the similarly-named variable in main()).
If you want to (conceptually) pass head by reference, you need to actually pass a pointer to it -- that is, in this case, a pointer to a pointer! You'd need to declare your function as
void Insert(Node **head, int x) { ... }
and call it as
Insert(&head, 25);
Then the actual parameter is a pointer to the variable head which gives the function a chance to update that variable, if you deference the parameter where appropriate:
// ...
temp->next = *head;
// ...
*head = temp;
// ...
Pass a pointer to a pointer to head. That way, you can set head to null.
void Insert(Node **head, int x) {
...
if (*head == NULL) {
*head = temp;
}
else {
...
*head->next = temp;
}
}
Usage:
Node *head = NULL;
Insert(&head, 10);
This line (after the '*' removal) does exactly nothing as it only changes the local headNode parameter ( and 100% will be removed completely by the compiler)
headNode = NULL;
If you want to assign NULL to the higher level pointer you need to pass node **headnode to this function or make it node *:. 1.
void clear(node** headNode){
node* nextNode;
if (*headNode == NULL) return;
while (*headNode -> next != NULL){
nextNode = *headNode -> next;
free(*headNode);
*headNode = nextNode;
}
*headNode = NULL;
}
and the call
clear(&list);
or better
node *clear(node* headNode){
node* nextNode;
if (headNode == NULL) return;
while (headNode -> next != NULL){
nextNode = headNode -> next;
free(headNode);
headNode = nextNode;
}
return NULL;
}
and the call :
list = clear(list);
Change line :
*headNode = NULL;
to :
headNode = NULL;
and the error will disappear.
Also, do not cast the result of malloc and always check if malloc was successful.