Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement test_realloc #284

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

chensheep
Copy link

Added test_realloc implementation referencing https://danluu.com/malloc-tutorial/.

Change-Id: I87149ac233572dece7f3ec8b7d3320d07544f855

Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve git commit messages, addressing the motivation and considerations.

@chensheep chensheep force-pushed the dev_test_realloc branch 2 times, most recently from b2ae174 to 0344bb8 Compare March 27, 2025 04:24
Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't mention file name in the subject of git commit messages. Read https://cbea.ms/git-commit/ and CONTRIBUTING.md carefully. Then, improve the commit messages by writing informative sentences.

This commit implements test_realloc and makes it
possible to adjust the memory size allocated by
test_malloc() or test_calloc().

In this commit, there is still room for improvement.
When we shrink the allocated memory size, we simply
return the original array. This may lead to unused
memory. Therefore, we can improve this in the future.

Reference:
  https://danluu.com/malloc-tutorial/

Change-Id: Ic85b35cfff4dc0b6a46a6e81e6c1ce873625f0ac
Comment on lines +194 to +205
* This function implements how to adjust the size of memory allocated
* by test_malloc or test_calloc.
*
* First, we check whether the memory is already allocated.
* If it wasn't allocated (p is NULL),
* the fucntion behaves like test_malloc, returning a newly allocated memory.
*
* Otherwise, we check the payload size of the orignal memory.
* - If new_size is less than or equal to it, return the original memory.
* - If new_size is greater than it, we allocate a new memory with new_size.
* Copy the contents from the orginal memory to the newly allocated memory
* ,and then free the original one. Finally, we return the newly one.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shorten the descriptions.


const block_element_t *b = find_header(p);
if (b->payload_size >= new_size)
// TODO: Free some once we implement split.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Show more about this operation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provide the improvements within this pull request.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the current implementation has its pros and cons. Since we do not shrink the memory size, it performs well in cases like the following:

malloc(100) -> realloc(1) -> realloc(2) -> realloc(3)

In this scenario, when we allocate a large block of memory and then reduce its size, later extensions of the memory (to a larger size) will not require additional work to handle.

Here, I propose a simple improvement:

If new_size is larger than old_size, we allocate new_size * 2 for future use.

If new_size is smaller than old_size, we check whether new_size * 2 is still smaller than old_size. If so, we allocate new memory with new_size * 2 to optimize memory usage. Otherwise, we retain the old_size.

This approach wastes some memory but reduces the number of memory copy operations when calling realloc.

Apart from the above method, I also tried implementing it using the C function realloc, but the documentation does not guarantee under what circumstances it will move the pointer (allocate new memory). This uncertainty makes it difficult to implement a noallocate_mode.

Another approach is to split the unused memory into a separate block. However, this increases the complexity of implementing test_malloc and test_free. We would need an additional field in the block to indicate whether it is free or not. In test_malloc, the simplest implementation would iterate through the list to find a free block with enough space, which increases time complexity compared to the current implementation. In test_free, to avoid excessive fragmentation, we would need to implement a function to merge adjacent free memory blocks, adding further complexity.

I am unsure whether this is worth pursuing, as this module is primarily used for detecting memory usage rather than optimizing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants