There are a variety of problems, some serious, some mundane.
The free(x)
at the bottom of createArray()
is unreachable code; both the if
and else
clauses before it end with return. You are leaking the memory you allocate in createArray()
— you are not successfully returning a pointer to the memory to the main()
function (and you aren't attempting to release it there either), and you are not successfully releasing it in the function — which wouldn't be much like a 'create array' function if it also destroyed the array it created.
One interpretation of the requirements (call it "Interpretation A") is that your function should be returning an int *
, not an int
. You might be getting a warning about the return NULL
converting a pointer to an integer (possibly mentioning 'different size').
Under this interpretation, the code in main()
should probably use int *firstDigit = createArray(…);
. Then the comparison in else if (firstDigit == NULL) {
is correct — but the prior if (firstDigit > 0)
is dubious and you should actually reverse the testing:
if (firstDigit == NULL)
{
fprintf(stderr, "Something went wrong with memory allocation\n");
exit(1);
}
printf("First digit is: %d\n", firstDigit[0]);
Note that:
- errors go to stderr;
- messages end with newlines;
- programs should exit with a non-zero status on failure.
Under this interpretation, you wouldn't pass pt
or &pt
to the function; you'd simply assign the return value from the function to pt
.
However, an alternative interpretation (call it "Interpretation B") is that you are trying to assign the pointer to the allocated memory to pt
in main()
, but then you have a pointer type mismatch in the arguments to createArray()
. That isn't helping your cause either.
Fixed code for Interpretation A:
/* SO 6463-4370 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static int *createArray(int size)
{
int low = 2;
int high = 8; /* Increased from 5 to 8 */
int *x = (int *) malloc(size * sizeof(int));
if (x == NULL)
{
fprintf(stderr, "Memory cannot be allocated\n");
exit(1);
}
// filling the array with random numbers from [low;high]
for (int i = 0; i < size; ++i)
{
x[i] = low + rand() % (high - low + 1);
}
// returning a pointer to the first digit of the new array
return x;
}
int main(void)
{
srand(time(NULL));
int size = 5;
int *pt = createArray(size);
if (pt == NULL)
{
fprintf(stderr, "Something went wrong\n");
exit(1);
}
printf("First digit is: %d\n", pt[0]);
for (int i = 0; i < size; i++)
printf(" [%d] %d\n", i, pt[i]);
free(pt);
return 0;
}
Output from Interpretation A:
First digit is: 5
[0] 5
[1] 8
[2] 6
[3] 6
[4] 2
Fixed code for Interpretation B:
/* SO 6463-4370 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static int createArray(int **pt, int size)
{
int *x;
int count = 0;
int low = 2;
int high = 5;
x = (int *) malloc(size * sizeof(int));
if (x == NULL)
{
fprintf(stderr, "Memory cannot be allocated\n");
exit(1);
}
// filling the array with random numbers from [low;high]
for (int i = 0; i < size; ++i)
{
x[i] = low + rand() % (high - low + 1);
++count;
}
// Assigning a pointer to the first digit of the new array,
// and returning the first digit of the array
*pt = x;
return x[0];
}
int main(void)
{
srand(time(NULL));
int *pt;
int size = 5;
int firstDigit = createArray(&pt, size);
if (firstDigit == 0)
{
fprintf(stderr, "Something went wrong\n");
exit(1);
}
printf("First digit is: %d\n", firstDigit);
for (int i = 0; i < size; i++)
printf(" [%d] %d\n", i, pt[i]);
free(pt);
return 0;
}
Output from Interpretation B:
First digit is: 3
[0] 3
[1] 3
[2] 2
[3] 4
[4] 4
I will observe that Interpretation B is less flexible and less like idiomatic C code. It's not wrong, but it isn't the way it is normally done. The first digit is easily obtained when you have the whole array. We can also debate the wisdom of exiting from within the function — it would be better to return the null pointer and have the calling code report the error. This is particularly true for code that will live in a library. This also affects the design of the function.