I'm dynamically allocating an array in main() to store the prime factors of any number calculated through a PrimeFactors() function I coded myself. Problem is, when the size of the array >= 4, the program displays what looks like undefined behavior; reading garbage values and whatnot. Works perfectly when size < 4.
I thought that maybe the array address was changing through the function and as a consequence main() would read garbage values, not knowing the "new" address of the array; and it seems like this is the case.
OS is Linux Ubuntu 18.04 LTS.
As i am learning I do not want to simply use vector and forget about this problem.
Why is this happening and what could I do to fix this ? I am clueless and it seems google and SO are as well.
Here's the main() code :
int main(int argc, char* argv[])
{
unsigned long long n = atoll(argv[1]);
unsigned long long* factors = malloc(sizeof(unsigned long long));
if(factors == NULL)
{
printf("malloc failed to allocate factors\n");
return -1;
}
else
printf("First address in main() %p\n\n", (void *)&(factors[0]));
unsigned short int* size = malloc(sizeof(unsigned short int));
if(size == NULL)
{
printf("malloc failed to allocate size\n");
return -1;
}
PrimeFactors(factors, size, n);
printf("Last address in main() : %p\n", (void *)&(factors[0]));
for(int i = 0; i < *size; ++i)
printf("%llu\n", factors[i]);
free(factors);
free(size);
return 0;
}
And here's the PrimeFactors() code :
int PrimeFactors (unsigned long long* factors, unsigned short int* size, unsigned long long n)
{
printf("In PrimeFactors() :\n");
*size = 2;
factors = realloc(factors, (*size) * sizeof(unsigned long long));
if (factors == NULL)
{
printf("realloc failed re-allocating factors array\n");
return -1;
}
else
printf("realloc() %d address in PrimeFactors() : %p\n", *size, (void *)&(factors[0]));
if (IsPrime(n))
{
factors[0] = n;
return 0;
}
unsigned short int factorsCount = 0;
for (unsigned long long i = 2; i <= n; ++i)
{
while(n % i == 0)
{
if(factorsCount >= *size)
{
factors = realloc(factors, ++(*size) * sizeof(unsigned long long));
if (factors == NULL)
{
printf("realloc failed re-allocating factors array\n");
return -1;
}
else
printf("realloc() %d address : %p\n", *size, (void *)&(factors[0]));
}
factors[factorsCount] = i;
++factorsCount;
n /= i;
}
}
printf("last address in PrimeFactors() : %p\n", (void *)&(factors[0]));
for(int i = 0; i < *size; ++i)
printf("%llu\n", factors[i]);
printf("Exiting PrimeFactors()...\n\n");
return 0;
}
Compile flags :
gcc -Wall -Wshadow -Wpointer-arith main.c libMath.c -o learnlab.exe
Execute command :
./learnlab 80
Expected output :
First address in main() 0x5626aa180260
In PrimeFactors() :
realloc() 2 address in PrimeFactors() : 0x5626aa180260
realloc() 3 address : 0x5626aa180260
realloc() 4 address : 0x5626aa180260
realloc() 5 address : 0x5626aa180260
last address in PrimeFactors() : 0x5626aa180260
2
2
2
2
5
Exiting PrimeFactors()...
Last address in main() : 0x5626aa180260
2
2
2
2
5
Actual output :
First address in main() 0x5626aa180260
In PrimeFactors() :
realloc() 2 address in PrimeFactors() : 0x5626aa180260
realloc() 3 address : 0x5626aa180260
realloc() 4 address : 0x5626aa1812b0
realloc() 5 address : 0x5626aa1812b0
last address in PrimeFactors() : 0x5626aa1812b0
2
2
2
2
5
Exiting PrimeFactors()...
Last address in main() : 0x5626aa180260
0
2
2
4113
7233098161058900294
Sorry this is a long post, I couldn't really figure out a way to make it shorter. Thank you.