1
typedef struct _DocumentRow
{
    char * code /** The code */;
    char * designation /** The designation */;
    double quantity /** The quantity */;
    char * unity /** The unity */;
    double basePrice /** The base price */;
    double sellingPrice /** The selling price */;
    double discount /** The discount */;
    double rateOfVAT /** The rate of VAT */;
    struct _DocumentRow * next /** The pointer to the next row */;
} DocumentRow;

void DocumentRowList_init(DocumentRow ** list) {
    DocumentRow *L;
    list = ( DocumentRow ** ) malloc( sizeof( DocumentRow* ) );
    if ( list == NULL ) {
        fatalError( "memory is not enough" );
    }
    L = NULL;
    list = &L;
}

After using the function DocumentRowList_init, when I test if ( *list == NULL ), it evaluates to false, why ? I have already set list = &L and L = NULL.

7
  • don't follow you question... if *list==NULL returns 0, *list is not NULL. Commented Jan 3, 2014 at 8:06
  • 1
    list is local. *list = L; to set. Commented Jan 3, 2014 at 8:06
  • 1
    To me, this code seems to do nothing, e.g. L = NULL; list = &L;?! Commented Jan 3, 2014 at 8:07
  • also L = malloc( sizeof( DocumentRow ) ); if(L == NULL) ... Commented Jan 3, 2014 at 8:08
  • 1
    What you wrote is called a memory leak. You allocate memory pointed by list and then you make list to point somewhere else. You will not be able to free(list). And *list is not NULL because *list is L which is a pointer to NULL. Outside this function, testing *list may result in a segmentation fault. Commented Jan 3, 2014 at 8:12

3 Answers 3

2

You would have undefined behaviour here. L is a local variable, so when you return it's address via the pointer pointer, the variable no longer exists when DocumentRowList_init is returning.

So even though you assign NULL to it, it will point to invalid memory.

But list is local to DocumentRowList_init, so it will not return the value anyway, as you only assign it a value and then return.

If you want to return a structure of DocumentRow you'd have to use this

  *list = malloc( sizeof *L);

to allocate a structure and return the pointer to it.

Sign up to request clarification or add additional context in comments.

Comments

2

Looks like you want to change (initialize) something pointed to by list, here is how it usually be done:

void DocumentRowList_init(DocumentRow ** list) {
    *list = ( DocumentRow * ) malloc( sizeof( DocumentRow ) );
    if ( *list == NULL ) {
        fatalError( "memory is not enough" );
    }
}

1 Comment

You malloc only size(DocumentRow*) bytes for a pointer, not size(DocumentRow) for the struct. In this case the type cast to ( DocumentRow ** ) is correct.
0
void DocumentRowList_init(DocumentRow ** list) {
    DocumentRow *L;
    list = ( DocumentRow ** ) malloc( sizeof( DocumentRow* ) );
    if ( list == NULL ) {
        fatalError( "memory is not enough" );
    }
    L = NULL;
    list = &L;
}

Please mind that list=&L assigns list the address of a variable located on the stack. So once you exist the function the variable is out of scope and your list is left pointing to a some location (on the stack).

2 Comments

So, what can I do ? I want to make *list = NULL, but it also can't work
you can make DocumentRow *L a global variable; or dynamically allocate memory for L: L= (DocumentRow *)malloc(sizeof(DocumentRow *))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.