1

I have the following code, I pass the same pointer to both functions but I can only print out array elements in addNewValue function.

I do the same for printArray but the program stop and does not print anything.

What should I do to fix this problem, I have searched on stackoverflow but it seems like I can't find the answer for my problem.

int main()
{
    int *array = NULL;
    int value;
    int length = 0;
    int *lengthP = &length;

    printf("Enter new value");
    scanf("%d", &value);

    addNewValue(array, value, lengthP);

    printArray(array, lengthP);

    return 0;
}

void printArray(int* array, int* lengthP)
{
    int i = 0;
    int length = *lengthP;

    for(i = 0; i < length; i++)
    {
        printf("%d\n", *array[i]);
    }
}

void addNewValue(int* array, int value, int* lengthP)
{   
    *lengthP = *lengthP + 1;
    int length = *lengthP;

    array = realloc(array, length * sizeof(int));

    if(array == NULL)
    {
        printf("Error");
        return;
    }

    array[length - 1] = value;

    printf("%d", array[0]); 
}
melpomene
  • 84,125
  • 8
  • 85
  • 148
Thuan Nguyen
  • 431
  • 6
  • 18
  • 2
    you are not changing the `array` pointer in your main function. – Osiris Sep 10 '18 at 14:01
  • @Osiris but i pass the pointer to addNewValue function, and i add new element to the array, so i think it should change the array pointer in main too? – Thuan Nguyen Sep 10 '18 at 14:04
  • 2
    No the pointer is passed by value, like everything in C. You change the copy of the pointer which was created at the function call. – Osiris Sep 10 '18 at 14:05
  • debugger; breakpoint; examine variables; find null-pointer dereference – Mawg says reinstate Monica Sep 10 '18 at 14:06
  • @Osiris So my array pointer points to NULL at first, and if i want to change it with realloc, the only i can do it is to have another pointer, points to my array pointer and pass it to the function? – Thuan Nguyen Sep 10 '18 at 14:10
  • 1
    @ThuanNguyen Yes, or you return the new array pointer. You also do not need to create a pointer you can just call the function with `&var` as argument. – Osiris Sep 10 '18 at 14:11
  • 1
    It is almost always confusing to use the same name for a parameter within a function and in the calling code. The `array` inside `printfArray` is a copy of the `array` in main, and the `array` inside `addnewValue` is a different copy. If you get in the habit of using different names, it can help you avoid the mistake of thinking you're looking at the same object. – Tim Randall Sep 10 '18 at 14:14

2 Answers2

2

Whatever your function addNewValue(array, value, lengthP) does, it will never change the value the pointer array passed to it. Note that array in main and array in addNewValue are two different variables; the value of the former (i.e. a "memory address") is copied into the value of the latter, and addNewValue is changing a copy, not the original pointer value from main. Hence, array will always be NULL. Hence, you'll dereference NULL and yield undefined behaviour.

Change

void addNewValue(int* array, int value, int* lengthP) 

to

void addNewValue(int** array, int value, int* lengthP) 

and call it using

addNewValue(&array, value, lengthP) 

Adapt the logic in addNewValue accordingly.

Achal
  • 11,821
  • 2
  • 15
  • 37
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
2

Because you don't modify the array of main (and that allocated in addNewValue is leaked BTW).

int main() {
    int *array = NULL;
    int value = 42;
    int length = 0;
    int *lengthP = &length;
    addNewValue(&array, value, lengthP);
    printArray(array, lengthP);
}

void addNewValue(int** array, int value, int* lengthP) {   
    *lengthP = *lengthP + 1;
    int length = *lengthP;

    *array = realloc(*array, length * sizeof(int));

    if(*array == NULL) { /* ... */ }

    (*array)[length - 1] = value;
}
bipll
  • 11,747
  • 1
  • 18
  • 32