Coderzelf
Coderzelf

Reputation: 752

Can I change the value in my struct object like this?

I don't know how to pass a pointer to functions and change the values that pointer pointing to,

I did it like this:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

struct node{
    struct node* lchild;
    struct node* rchild;
    struct node* p;
    int noChild;
    char* data;
    int height;
};

typedef struct node text_t;

text_t * create_text(){
    text_t * txt = NULL;
    return txt;
}

int length_text(text_t *txt){
    if(txt == NULL)return 0;
    return txt->noChild+1;
}

char * get_line(text_t * txt, int index){
     if(index>txt->noChild+1) return NULL;

     text_t * current = txt;
     while((current->noChild+1)!=index-1){
        if(index-1>current->noChild+1){
           current = current->rchild;
           }else{
             current = current->lchild;
             }                                                     
     }
     return current->data;
}

void append_line(text_t *txt, char * new_line){     
      text_t * temp;

      if (txt == NULL){

       txt = (text_t *)malloc(sizeof(text_t));
       txt->lchild = NULL;
       txt->rchild = NULL;
       txt->noChild = 0;
       txt->p = NULL;
       txt->data = new_line;
       txt->height = 1;
       printf(txt->data);
     }else{
       text_t * current = txt;

       while(current->rchild!=NULL){
       current = current->rchild;
       }

       temp = (text_t *)malloc(sizeof(text_t));
       temp->lchild = NULL;
       temp->rchild = NULL;
       temp->noChild = 0;
       temp->data = new_line;
       temp->height = 1;
       temp->p = current;

}}    







int main()
{  int i, tmp; text_t *txt1, *txt2; char *c;
   printf("starting \n");
   txt1 = create_text();//1
   txt2 = create_text();

   append_line(txt1, "line one" );//2
 ...

I want to create an object of such a struct in C and use it to build a balanced tree.

However, after I did append_line(), nothing changes with txt1, it's still NULL. Why?

Thanks

Upvotes: 0

Views: 191

Answers (3)

D.Shawley
D.Shawley

Reputation: 59563

txt1 is a pointer to a node. Think of a pointer as nothing more than a numeric address that is passed into append_line. The txt argument to append_line receives the numerical address of txt1 holds. If you were to modify the members inside of txt, then you would be modifying what txt1 points to. However, when you assign a new value to txt in append_line, you are overwriting the numerical address that resides in the txt variable. This has absolutely no effect on txt1 -- instead, it makes txt point to a new value.

If you want to assign a new value to a pointer, then you have to pass a pointer to it. In other words, you need to pass a pointer to a pointer. Consider the following version:

void append_line(text_t **h, char *new_line) {
    if (*h == NULL) {
        *h = (text_t*)malloc(sizeof(text_t));
        (*h)->lchild = NULL;
        (*h)->rchild = NULL;
        /* rest of if block */
    } else {
        text_t *temp;
        text_t *current = *h;
        /* rest of else block */
    }
}

int main() {
    int i, tmp; text_t *txt1, *txt2; char *c;
    printf("starting \n");
    txt1 = create_text();
    txt2 = create_text();
    /* txt1 is a pointer to text_t
     * &txt1 is a pointer to a pointer of text_t
     */
    append_line(&txt1, "line one" );
...

Upvotes: 0

ughoavgfhw
ughoavgfhw

Reputation: 39905

In C, function parameters are passed by value. This means that any changes you make to a parameter within the function are not visible outside the function. You get around this by passing a pointer to the data you want to be modified. This makes changes to the data which the parameter points to visible outside the function, but since the pointer itself is passed by value, any changes to it won't be visible. In order to make that change visible, you need a pointer to a pointer.

void append_line(text_t **txt, char * new_line){     
  if (*txt == NULL){
    *txt = (text_t *)malloc(sizeof(text_t));
    *txt->lchild = NULL;
    ...

// in main
text_t *txt1 = create_text();//1
append_line(&txt1, "line one" );//2

Alternately, you could return the new value of txt from your append_line function.

text_t* append_line(text_t *txt, char * new_line){     
  if (txt == NULL){
    txt = (text_t *)malloc(sizeof(text_t));
    txt->lchild = NULL;
    ...

  return txt;
}

// in main
text_t *txt1 = create_text();//1
txt1 = append_line(txt1, "line one" );//2

Upvotes: 0

Mahesh
Mahesh

Reputation: 34625

It's because c is pass by value.

 void append_line(text_t *txt, char * new_line){ 
   // ....

   txt = (text_t *)malloc(sizeof(text_t));

   // .....
 }

 int main() {
   // ...
   append_line(txt1, "line one" );
   // ...
 }

txt1 in main isn't affected with the malloc statement in the appen_line to txt. If you want to affect the txt1 in main then change the function text_t parameter to pointer to a pointer.

void append_line(text_t **txt, char * new_line);

Now pass the address of txt1 from main -

append_line(&txt1, "line one" );

Upvotes: 2

Related Questions