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;
}
How can I return a struct from a function?
C++ return null struct from function - Stack Overflow
function cannot return null in c - Stack Overflow
c - Why is my struct pointer creating function returning NULL because of a local declaration? - Stack Overflow
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.
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
}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.
Hi! I started learning C a few months ago and I'm working on a simple application, it doesn't really matter.
What matters is that I'm not sure if I'm doing it alright. The application has an array of pointers to user structures, and I want this function to return a pointer to a structure that has the correct id.
I just wonder if it is required to check if the pointer isn't NULL for every pointer in the array, or is there a better way to do it?
And I know that it would be easier to read with typedefs (probably) but it's easier for me to understand what exactly I have to pass to the function :>
I also made sure for the function to return NULL if there is no user with the given id.
I tested this code and it works, I just don't know if there's a better way to do it, if it's readable or if my way of thinking is wrong/correct.
I just want to improve :3
enum UserRole {
REGULAR,
ADMIN,
MASTER
};
struct User {
enum UserRole role;
uint64_t id;
char* name;
char* surname;
};
struct User *get_user_by_id(struct User* users[MAX_USERS_AMOUNT], uint64_t id)
{
for (int i = 0; i < MAX_USERS_AMOUNT; i++) {
if (users[i] != NULL && users[i]->id == id) {
return users[i];
}
}
return NULL;
}Better option is to pass the user count to the function, so you don't need to iterate over the max length. Otherwise yes, you would need to check for null.
I would do that like this:
if (users[i] && users[i]->id == id) { ... }
using users[i] instead of users[i] != NULL because NULL is equal to 0 and any non-zero value is like true
You also need to check users because arrays are like pointers and they can be NULL so any use of the [] operator will result in an error.
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.
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.