1

I was wondering what happens with the memory when u realloc -1 your array. According everything that I've read about realloc I suppose that pointer still points at the same place in memory (there's no need for function to seek another block of memory as that one is available and sufficient), tell me if I'm wrong. My question is: Is the deleted piece of array deleted (like with using free()) or are the values stay untouched and the piece of memory is being shared for future operations of malloc, calloc etc.?

EDIT: I have one more question. Does this function work properly? It should delete element of array previously overwriting it by the next element of the array. Doing it over the whole array, the last element is the same as the one before last and the last one is deleted. PicCounter is the number of pictures already uploaded to program. Check this out:

int DeletePicture(struct Picture **tab, int *PicCounter)
{
int PicToDelete;
printf("Enter the number of pic to delete ");
scanf("%d", &PicToDelete);
for (int i = PicToDelete - 1; i < (*PicCounter) - 2; i++)
{
    (*tab)[i] = (*tab)[i + 1];
}

struct Picture *temp;
temp = realloc(*tab, ((*PicCounter)-1) * sizeof(*temp));
if (temp != NULL)
{
    *tab = temp;
 //That doesn't delete the element, because in main I can still print it
 //like e.g. tab[lastelement]. 
    (*PicCounter)--;
    printf("Picture has been deleted\n");
    return 0;
}
else
{
    printf("Memory reallocation error\n");
    return 1;
}
}
MASTER OF CODE
  • 302
  • 3
  • 14
  • @AnttiHaapala: The question you marked this as a duplicate asks about the immediate use of `realloc`: What memory is usable afterward and whether the address changes when the allocation is being reduced. This question asks about a different effect of `realloc`: Whether, if the memory is reduced and `realloc` returns the same address, the memory that was requested to be released is then available for other allocation. These are not the same question. – Eric Postpischil Dec 25 '18 at 15:21
  • Actually it will be good to know answer for both of this questions, but you're right, it's not the same and now I can see that. However it doesn't solve my problem. – MASTER OF CODE Dec 25 '18 at 15:28
  • Answering your later question of “Does this function work properly?” is out of scope for Stack Overflow. However, note that, if `realloc` cannot allocate memory for a new object, the old object is not deallocated. Therefore, you do not need to report a memory reallocation error in this case. The old pointer remains valid, so the program can continue. – Eric Postpischil Dec 25 '18 at 15:47
  • Sidenote: As `realloc` accepts `size_t`, which is unsigned, -1 will be converted to a very large value your memory most likely is not capable to hold - and you'll experience the behaviour Eric described above... – Aconcagua Dec 25 '18 at 15:49

1 Answers1

3

Regarding void *realloc(void *ptr, size_t size), the C standard says in C 2018 7.22.3.5 paragraphs 2 and 3:

The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.

If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined. If size is nonzero and memory for the new object is not allocated, the old object is not deallocated. If size is zero and memory for the new object is not allocated, it is implementation-defined whether the old object is deallocated. If the old object is not deallocated, its value shall be unchanged.

What this means when you ask to reduce the size of a previously allocated object is:

  • The returned pointer might or might not be the same as the original pointer. (See discussion below.)

  • The C standard permits the portion of memory that is released to be reused for other allocations. Whether or not it is reused is up to the C implementation.

  • Whether the values in the released portion of memory are immediately overwritten or not is not specified by the C standard. Certainly the user of realloc may not rely on any behavior regarding that memory.

Discussion

When a memory allocation is reduced, it certainly seems “easy” for the memory allocation routines to simply return the same pointer while remembering that the released memory is free. However, memory allocation systems are fairly complex, so other factors may be involved. For example, hypothetically:

  • To support many small allocations without much overhead, a memory allocation system might create a pool of memory for one-to-four byte allocations, another pool for five-to-eight, another pool for eight-to-16, and a general pool for larger sizes. For the larger sizes, it might remember each allocation individually, customizing its size and managing them all with various data structures. For the smaller sizes, it might keep little more than a bitmap for each, with each bit indicating whether or not its corresponding four-byte (or eight or 16) region is allocated. In such a system, if you release eight bytes of a 16-byte allocation, the memory allocation software might move the data to something in the eight-byte pool.

  • In any memory allocation system, if you release just a few bytes at the end of an allocation, it might not be enough bytes to take advantage of—the data structures required to track the few bytes you released might be bigger than the few bytes. So it is not worthwhile to make them available for reuse. The memory allocation system just keeps them with the block, although it may remember the data in the block is actually a bit smaller than the space reserved for it.

Community
  • 1
  • 1
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312