Reputation: 87
I've been trying to make an example program using calloc and realloc and I've come across an issue where, when I make an array of integers smaller, it seems to remove the first element instead of the last one.
int *m = (int*)calloc(2, sizeof(int));
*m = 1;
*(m+1) = 2;
printf("\tInt 1: %d\n", m[0]);
printf("\tInt 2: %d\n\n", *(m+1));
// REALLOC
printf("How many elements the array have? ");
scanf("%d", &num);
*m = (int *)realloc(m, num * sizeof(int));
printf("ARRAY NOW HAS %d PLACES\n\n\t", num);
for(i = 0; i < num; i++) {
m[i] = i + 1;
printf("%d ", m[i]);
}
// DELETING MEMBERS OF AN ARRAY
while((d < 0) || (d > num)) {
printf("\n\nChoose which position of the previous array should be deleted (0 = first): ");
scanf("%d", &d);
}
printf("\nUPDATED ARRAY:\n\n");
for(i = d; i < num - 1; i++) {
m[i] = m[i + 1];
}
*m = (int *)realloc(m, (num - 1)*sizeof(int));
num--;
for(i = 0; i < num; i++) {
printf("%d ", m[i]);
}
An example of the program output would be:
Int 1: 1
Int 2: 2
How many elements the array have? 17
ARRAY NOW HAS 17 PLACES
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Choose which position of the previous array should be deleted (0 = first): 6
UPDATED ARRAY:
10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17
And if I include the last member of the array that should have been deleted (in this case m[16]) it shows:
10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17 17
Of course, I'm not entirely sure what's happening but it seems like it's just removing the value of m[0]?
Thanks in advance for any help!
Upvotes: 2
Views: 1739
Reputation: 153498
In addition to @dasblinkenlight good answer, when reducing the allocation size and the re-allocation fails (a rare event), code can simple continue with the original pointer.
Suggested re-write, assuming num > 0
:
// *m = (int *)realloc(m, num * sizeof(int));
void *t = realloc(m, sizeof *m * num);
if (t) {
m = t;
}
Upvotes: 0
Reputation: 726589
The reason the initial value gets modified is that you are assigning it:
*m = (int *)realloc(m, num * sizeof(int));
should be
m = realloc(m, num * sizeof(int));
Your code should also produce a warning, telling you that an assignment of a pointer to an array element containing int
s is invalid. Fixing this warning should have fixed your problem.
Note that an assignment of the form
m = realloc(m, ...);
where m
is used on both sides of realloc
is inherently unsafe, because realloc
could potentially return NULL
- for example, when there is not enough memory to allocate. Blind assignment to m
would render the old value of m
inaccessible, preventing proper deallocation. In production you should assign realloc
's result to a temporary, then check it for NULL
, and only then assign the result back to m
.
Upvotes: 2