Reputation: 13
the code is:
int main(int argc, const char* argv[] )
{
struct node * initialpointer=NULL;
insert("asd", initialpointer, 1);
if(initialpointer!=NULL)
printf("isnotnull");
if (initialpointer==NULL)
printf("isnull");
}
insert(char* x,struct node * initialpointer, int numberofelements){
struct node B;
B.word = x;
B.parent = NULL;
B.leftchild = NULL;
B.rightchild = NULL;
printf("%d", 12);
if ( initialpointer == NULL){
initialpointer = &B;
B.parent = NULL;
}
}
So in the end I want initialpointer
to point where nde B is but in the main method it prints it is null. So how can I change the initialpointer
in function insert permanently?
Upvotes: 0
Views: 712
Reputation: 122001
Do not return a pointer to a local variable, this will result in a dangling pointer:
struct node B;
...
initialpointer = &B;
You need to pass a pointer to a pointer to a struct node
to insert()
and malloc()
a new struct node
inside insert()
:
insert(char* x,struct node ** initialpointer, int numberofelements)
{
if (NULL == *initialpointer)
{
*initialpointer = malloc(sizeof(struct node));
if (*initialpointer)
{
/* Note: you should probably make a copy of 'x',
using 'strdup()' or similar, otherwise there
is requiremenet that 'x' exist for the lifetime
of '*initialpointer': which would be error prone. */
(*initialpointer)->word = x;
(*initialpointer)->parent = NULL;
(*initialpointer)->leftchild = NULL;
(*initialpointer)->rightchild = NULL;
}
}
}
This retains the logic of the original insert()
as a node
should only be created and assigned to initialpointer
if initialpointer
is NULL
.
And invoke it:
struct node * initialpointer=NULL;
insert("asd", &initialpointer, 1);
Remembering to free()
it when no longer required:
free(initialpointer);
Upvotes: 4
Reputation: 9134
Edited per @Paul Mitchell's comment.
int main(int argc, const char* argv[] )
{
struct node* initialpointer = insert("asd");
if ( initialpointer == NULL )
/* handle the error */
/* remember to free() all the allocated nodes */
}
struct node* insert(char* x)
{
struct node* initialpointer = (struct node*)malloc(sizeof(struct node));
if ( initialpointer == NULL)
return NULL;
initialpointer.word = x;
initialpointer.parent = NULL;
initialpointer.leftchild = NULL;
initialpointer.rightchild = NULL;
return initialpointer;
}
This will allocate a single node (I've removed the numberofelements
parameter).
To allocate space for more than a node, you have to pass a pointer to a pointer. But if I understand your intent, you want a node to be part of a linked structure, maybe a tree, so you don't need to create a container for the nodes, since you can traverse the structure to access the nodes.
Upvotes: 0
Reputation: 34654
This is problematic for two reasons.
First of all, you are changing a local-scope variable, since initialpointer
is a parameter of your function. That means, regardless of its type, what you write to the variable itself is only visible inside your insert
function. If you were writing to *initialpointer
that would be whole different story.
Now, what is even more problematic is that B
is a local variable that is sitting on the stack inside your function. Once that function is left, the storage location of B
will be invalid. Hence, if you return the pointer to B
, accessing that object outside of insert
will invoke undefined behaviour and will very likely not work (you have a slim chance that that particular location has not been altered, but that is pure luck).
What you probably want instead of
initialpointer = &B;
is this:
*initialpointer = B;
This will copy the B
object to the storage location that is referenced by the pointer variable. Now it is okay for B
to go out of scope, because you copied everything to the initialpointer
variable that is sitting inside main.
Note that the initialpointer
variable inside main
is a completely different thing than the one in insert
!
One last thing, giving variables names that start with uppercase letters is not valid in any naming scheme I came across so far.
Upvotes: 0
Reputation: 42825
There are a couple problems with your code.
First is the problem you're having. The pointer you're passing to insert
is passed by copy; the function gets a copy and main
doesn't see your change. The solution to this is to pass a pointer to the pointer. See the POSIX function strtol
for a standard library example of how this looks.
The second problem is that you're returning a pointer to a local, automatic (i.e. stack-allocated) variable. Since the stack is released on function exit, this pointer points to invalid memory when it is back in main
. So instead you need to allocate B
from the heap.
So, fixing things up:
int main(int argc, const char* argv[] )
{
struct node * initialpointer=NULL;
insert("asd", &initialpointer, 1);
if(initialpointer!=NULL)
printf("isnotnull");
if (initialpointer==NULL)
printf("isnull");
}
insert(char* x,struct node ** initialpointer, int numberofelements){
struct node *B;
B = (struct node*)malloc(sizeof(struct node));
B->word = x;
B->parent = NULL;
B->leftchild = NULL;
B->rightchild = NULL;
printf("%d", 12);
if ( *initialpointer == NULL){
*initialpointer = B;
B->parent = NULL;
}
}
Upvotes: 0
Reputation: 91139
struct node * initialpointer=NULL;
insert("asd", &initialpointer, 1);
...
void insert(char* x,struct node ** initialpointer, int numberofelements){
...
if ( *initialpointer == NULL){
*initialpointer = &B;
But keep in mind that this as well won't work with your current B
as auto (local) variable.
You must malloc()
B
.
And you are missing an else
branch in your if
statement.
Upvotes: 0