Here's what is really going on.
Let's take this example of some memory allocations packed together:
| some memory (10 bytes) | A (5 bytes) | unallocated (10 bytes) |
When you call realloc(A, 15) in the above scenario the system is able to expand the allocated memory at the same location:
| some memory (10 bytes) | A (15 bytes) |
However, what happens in the following case?
| some memory (10 bytes) | A (5 bytes) | some memory (10 bytes) |
This time, realloc(A, 15) can't simply expand the previously allocated region of memory since the latter 10 bytes it needs to expand A are currently allocated.
Instead, it has to do the equivalent of malloc()-ing a new memory region of 15 bytes and copying the original 5 bytes from A's old memory region to the first 5 bytes of the new region.
In that case, realloc() has not just expanded your memory allocation, but it has also moved the memory to a location where it can contiguously exist.
There are a few other reasons why realloc() would move memory (not just size requirements) but a lot of those are implementation defined.
Due to the possibility of a memory move, realloc() returns the address of the new pointer. As demonstrated above, sometimes it's the same pointer, and sometimes it's a new pointer.
When a move occurs, the old pointer is no longer valid as it is free()'d by the system. If you try to access it, you'll receive an access violation/segmentation fault.
In your example, you're realloc()-ing the memory in addValue() but you're never updating the caller's pointer. When the caller goes to use the old pointer, if a move occurred in addValue(), then the memory it tries to use will thus be invalid and the whole thing will crash and burn.
One way you could solve this is to pass a pointer to a pointer.
void addValue(int **A, int *n, int Data)
{
*A = realloc(*A, (*n+1)*sizeof(int *));
(*A)[*n] = Data;
(*n)++;
}
And call it appropriately:
addValue(&A, &nA, temp);
A final note: In C, you don't need to cast the result of malloc() or realloc() - unlike C++, void* is implicitly cast-able to any other pointer type.