1

I have created a pointer of type "Vector" (see code). After creation I want to send a pointer of type Vector (meaning Vector*) to a function called "VectorDestroy(Vector* _vector), which frees the struct from memory and assigns it to null. However when I continue in the code and want to test if the returned vector is null it fails; meaning it is not changed to null

This is the struct:

struct vector
{
    int* m_items;
    size_t m_originalSize; /*original allocated space for items*/
    size_t m_size; /*actual allocated space for items*/
    size_t m_nItems; /*actual number of items*/
    size_t m_blockSize; /*the chunk size to be allocated when no space available*/
    int m_magicNumber;

};

typedef struct vector Vector;

This is the external function VectorDestroy which is found in module1:

void VectorDestroy(Vector* _vector)
{   
    if(_vector == NULL || _vector->m_magicNumber != MAGIC_NUMBER)
    {
        return;
    }

    _vector->m_magicNumber = 0Xdeadbeef;
    free(_vector->m_items);
    _vector->m_items = NULL;
    free(_vector);
    _vector = NULL;
}

This is the test function which is found in module2:

int VectorDestroyFunctional()
{
    Vector* vector = VectorCreate(5, 5);

    if(vector == NULL)
    {
        PrintResult(FAIL);
        return FAIL;
    }

    VectorDestroy(vector);

    if(vector == NULL)
    {
        PrintResult(PASS);
        return PASS;
    }

    PrintResult(FAIL);
    return FAIL;
}

After the free() function in VectorDestroy and assigning the pointer to null I expected the pointer to be null and the test would pass, but in debugging I found out the pointer is not set to null and the test fails. Am I missing something?

  • Doesn't directly address your question, but you should avoid using leading underscores for variable names (e.g. `_vector`). Read more about why here: https://stackoverflow.com/a/25090719/3958521 – bigwillydos Apr 12 '19 at 22:49

2 Answers2

2

You nullified the local copy of the pointer. To nullify the pointer in the calling code, you'd need to pass a pointer to a pointer to the function:

void VectorDestroy(Vector **p_vector)
{   
    if (p_vector == NULL || *p_vector == NULL)
        return;
    Vector *vector = *p_vector;
    if (vector->m_magicNumber != MAGIC_NUMBER)
        return;

    vector->m_magicNumber = 0Xdeadbeef;
    free(vector->m_items);
    vector->m_items = NULL;
    free(vector);
    *p_vector = NULL;
}

and you'd call:

VectorDestroy(&vector);
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I tried the code and it worked. Many thanks. I still don't fully understand the subject of pointers. I used for example functions such as AddItem() and RemoveItem(), to both I sent Vector* vector, and when continuing in the code the values in the pointer I sent changed, I didn't need to define a pointer to pointer in order to do that – Majd Kharman Apr 12 '19 at 23:50
  • If you were only changing the values in the structure pointed at, the `Vector *` argument is sufficient. if you need to change the pointer itself (in the calling code, you need a pointer to that pointer to make the change). – Jonathan Leffler Apr 12 '19 at 23:52
1

You say:

After the free() function in VectorDestroy and assigning the pointer to null I expected the pointer to be null and the test would pass, but in debugging I found out the pointer is not set to null and the test fails. Am I missing something?

Yes. You forget that in C the parameters are always a copy of the variable they are initialized with. So by changing _vector you are changing the parameter and not the outer variable. If you want the function to be able to change the external pointer the declaration should be something like:

void VectorDestroy(Vector **vector_);

I took the liberty to move the underscore to the back, because you should avoid leading underscores.

Costantino Grana
  • 3,132
  • 1
  • 15
  • 35
  • Many thanks, I understand it better now. Regarding the underscore, I was instructed in the course I am taking that the underscore flags to other programmers that this is a parameter. Anyway I will take notice to avoid it from now on – Majd Kharman Apr 12 '19 at 23:52