Compare commits
13 commits
page_begin
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a09cf2de17 | ||
|
|
4f8a0bb720 | ||
|
|
de0af4715b | ||
|
|
56636b54c4 | ||
|
|
a531db5e3a | ||
|
|
b4f942f678 | ||
|
|
06fac933c2 | ||
|
|
5aba0ff0c3 | ||
|
|
ed8a843d3d | ||
|
|
7629201717 | ||
|
|
ac1b94ebc1 | ||
|
|
1e895ef74a | ||
|
|
fd1c0872a4 |
14 changed files with 504 additions and 0 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -1,3 +1,9 @@
|
||||||
a.out
|
a.out
|
||||||
|
*~
|
||||||
|
*.swp
|
||||||
*.o
|
*.o
|
||||||
*.a
|
*.a
|
||||||
|
*.so
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.core
|
||||||
|
|
|
||||||
11
alignment/alignment.c
Normal file
11
alignment/alignment.c
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "alignment.h"
|
||||||
|
|
||||||
|
size_t align(size_t size)
|
||||||
|
{
|
||||||
|
size_t res;
|
||||||
|
if (__builtin_add_overflow(
|
||||||
|
size, sizeof(long double) - (size % sizeof(long double)), &res))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
10
alignment/alignment.h
Normal file
10
alignment/alignment.h
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef ALIGNMENT_H
|
||||||
|
#define ALIGNMENT_H
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
size_t align(size_t size);
|
||||||
|
|
||||||
|
#endif /* !ALIGNMENT_H */
|
||||||
29
malloc/Makefile
Normal file
29
malloc/Makefile
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS=-std=c99 -pedantic -Werror -Wall -Wextra -Wvla -fvisibility=hidden -fPIC
|
||||||
|
CPPFLAGS= -D_DEFAULT_SOURCE
|
||||||
|
LDFLAGS= -shared -Wl,--no-undefined
|
||||||
|
LDLIBS=
|
||||||
|
|
||||||
|
SRCS=src/malloc.c src/helpers/helpers.c src/helpers/allocate.c
|
||||||
|
OBJS=${SRCS:.c=.o}
|
||||||
|
TST_OBJS = tests/test.o
|
||||||
|
TARGET=libmalloc.so
|
||||||
|
|
||||||
|
library: $(OBJS)
|
||||||
|
$(CC) -o $(TARGET) $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
debug: CFLAGS += -g
|
||||||
|
debug: $(OBJS)
|
||||||
|
$(CC) -o $(TARGET) $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
# test: LDLIBS += -lcriterion
|
||||||
|
test: CFLAGS = -g -L. -lmalloc -fPIC -fvisibility=hidden
|
||||||
|
test: library $(TST_OBJS)
|
||||||
|
$(CC) -o $(TST_TARGET) $^ $(LDLIBS)
|
||||||
|
|
||||||
|
check:
|
||||||
|
dash tests/test-cmd.sh
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OBJS)
|
||||||
|
$(RM) $(TARGET)
|
||||||
94
malloc/src/helpers/allocate.c
Normal file
94
malloc/src/helpers/allocate.c
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
#include "allocate.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
// c'est dangereux de pas s'i3lock
|
||||||
|
// coucou
|
||||||
|
void *allocate_block(struct bucket *biquette, int block_number)
|
||||||
|
{
|
||||||
|
if (block_number == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Update header
|
||||||
|
unsigned char byte_mask = 1 << (block_number % 8);
|
||||||
|
biquette->alloc_blk_cnt++;
|
||||||
|
biquette->free_map[block_number / 8] |= byte_mask;
|
||||||
|
|
||||||
|
// Compute block address
|
||||||
|
return get_block(biquette, block_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bucket *create_bucket(size_t min_alloc_size)
|
||||||
|
{
|
||||||
|
size_t page_alloc_size;
|
||||||
|
size_t block_alloc_size;
|
||||||
|
|
||||||
|
if (min_alloc_size > PAGE_SIZE - sizeof(struct bucket))
|
||||||
|
{
|
||||||
|
// Huge page
|
||||||
|
page_alloc_size = min_alloc_size + sizeof(struct bucket);
|
||||||
|
block_alloc_size = page_alloc_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Regular page
|
||||||
|
page_alloc_size = PAGE_SIZE;
|
||||||
|
block_alloc_size = s2p(min_alloc_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get page
|
||||||
|
void *page = mmap(NULL, page_alloc_size, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
|
||||||
|
if (page == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Init bucket
|
||||||
|
struct bucket *header = page;
|
||||||
|
header->block_size = block_alloc_size;
|
||||||
|
header->alloc_blk_cnt = 0;
|
||||||
|
header->alloc_size = page_alloc_size;
|
||||||
|
memset(header->free_map, 0, FREE_LIST_SIZE);
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_block(void *ptr, struct bucket **list)
|
||||||
|
{
|
||||||
|
// Compute header location and block number
|
||||||
|
struct bucket *header = get_page_begin(ptr);
|
||||||
|
|
||||||
|
// Verify that header belongs to list
|
||||||
|
struct bucket *elt = *list;
|
||||||
|
int found = 0;
|
||||||
|
while (elt != NULL)
|
||||||
|
{
|
||||||
|
if (elt == header)
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elt = elt->next;
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// free in map and update size
|
||||||
|
int block_number = get_block_number(header, ptr);
|
||||||
|
if (block_number == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned char byte_mask = 1 << ((block_number % 8));
|
||||||
|
header->free_map[block_number / 8] &= ~byte_mask;
|
||||||
|
header->alloc_blk_cnt--;
|
||||||
|
|
||||||
|
// Huge page
|
||||||
|
// free bucket if necessary
|
||||||
|
if (header->alloc_blk_cnt == 0)
|
||||||
|
{
|
||||||
|
bucket_list_remove(list, header);
|
||||||
|
munmap(header, header->alloc_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
13
malloc/src/helpers/allocate.h
Normal file
13
malloc/src/helpers/allocate.h
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef ALLOCATE_H
|
||||||
|
#define ALLOCATE_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
void *allocate_block(struct bucket *biquette, int block_number);
|
||||||
|
struct bucket *create_bucket(size_t min_alloc_size);
|
||||||
|
void bucket_append(struct bucket **head, struct bucket *elt);
|
||||||
|
void free_block(void *ptr, struct bucket **list);
|
||||||
|
|
||||||
|
#endif // ! ALLOCATE_H
|
||||||
170
malloc/src/helpers/helpers.c
Normal file
170
malloc/src/helpers/helpers.c
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
// Returns the smallest power of 2 greater or equal to s
|
||||||
|
size_t s2p(size_t s)
|
||||||
|
{
|
||||||
|
// Trick I found on the internet but I don't completely understand it
|
||||||
|
// Quite amazing
|
||||||
|
// n--; // 1101 1101 --> 1101 1100
|
||||||
|
// n |= n >> 1; // 1101 1100 | 0110 1110 = 1111 1110
|
||||||
|
// n |= n >> 2; // 1111 1110 | 0011 1111 = 1111 1111
|
||||||
|
// n |= n >> 4; // ...
|
||||||
|
// n |= n >> 8;
|
||||||
|
// n |= n >> 16; // 1111 1111 | 1111 1111 = 1111 1111
|
||||||
|
// n++; // 1111 1111 --> 1 0000 0000
|
||||||
|
|
||||||
|
// There is also an x86 assembly instruction to do that in a single cycle:
|
||||||
|
// lzcnt
|
||||||
|
// Yeah... This one is definetely wild intel
|
||||||
|
// Now since asm{} is prohibited in the coding style it won't be useful
|
||||||
|
// Or maybe there is a builtin to do that ?
|
||||||
|
// (found __builtin_clzll but not sure of what it does)
|
||||||
|
|
||||||
|
// So here's the good old way
|
||||||
|
size_t n = MIN_BLOCK_SIZE;
|
||||||
|
while (n < s)
|
||||||
|
{
|
||||||
|
n <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_free_block(struct bucket *buck)
|
||||||
|
{
|
||||||
|
// Huge pages
|
||||||
|
if (buck->block_size > BUCKET_SIZE)
|
||||||
|
{
|
||||||
|
// Check block 0
|
||||||
|
if (!(buck->free_map[0] & (1 << 0)))
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t num_blocks_in_page =
|
||||||
|
(PAGE_SIZE - sizeof(struct bucket)) / buck->block_size;
|
||||||
|
size_t maplength = (num_blocks_in_page + 7)
|
||||||
|
/ 8; // +7 for ceiling division (oui c'est moche mais ça marche)
|
||||||
|
|
||||||
|
// Foreach byte
|
||||||
|
for (unsigned i = 0; i < maplength; i++)
|
||||||
|
{
|
||||||
|
unsigned char map_byte = buck->free_map[i];
|
||||||
|
if (map_byte == 0xFF) // Skip if used
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (unsigned j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
if ((i * 8 + j) < num_blocks_in_page
|
||||||
|
&& !(map_byte & (1 << j))) // Check if free
|
||||||
|
return i * 8 + j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Computes the block address based on its position in the freemap
|
||||||
|
void *get_block(struct bucket *biquette, int block_number)
|
||||||
|
{
|
||||||
|
if (block_number == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *data_begin = get_data_begin(biquette);
|
||||||
|
return data_begin + (biquette->block_size * (block_number));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets block position in the freemap based on its address
|
||||||
|
int get_block_number(struct bucket *biquette, void *block)
|
||||||
|
{
|
||||||
|
if (block == NULL || biquette == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
char *block_nul = block;
|
||||||
|
char *bibiche =
|
||||||
|
get_data_begin(biquette); // Célèbre bar Capcinois, venez à l'occasion
|
||||||
|
|
||||||
|
return (block_nul - bibiche) / biquette->block_size;
|
||||||
|
|
||||||
|
// Au revoir mes belles
|
||||||
|
// Vous manquerez à papa
|
||||||
|
// (mais fallait marcher, là ça marche pas)
|
||||||
|
|
||||||
|
// void *biquetteounette = biquette;
|
||||||
|
// char *biquette_cherie = biquetteounette;
|
||||||
|
|
||||||
|
// return (block_nul - biquette_cherie - sizeof(struct bucket))
|
||||||
|
// / biquette->block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a bucket with at least a block_size of size
|
||||||
|
// Returns NULL if nothing was found
|
||||||
|
struct bucket *get_bucket(struct bucket *head, size_t size)
|
||||||
|
{
|
||||||
|
while (head != NULL)
|
||||||
|
{
|
||||||
|
if (head->block_size >= size)
|
||||||
|
return head;
|
||||||
|
|
||||||
|
head = head->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Computes the buckets first block address
|
||||||
|
void *get_data_begin(struct bucket *biquette)
|
||||||
|
{
|
||||||
|
void *maisqueltrucdemerde = biquette;
|
||||||
|
char *biquettas = maisqueltrucdemerde;
|
||||||
|
return biquettas + sizeof(struct bucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Computes the beginning address of the page containing ptr
|
||||||
|
void *get_page_begin(void *ptr)
|
||||||
|
{
|
||||||
|
size_t quelenfer = ((size_t)ptr) & ~(PAGE_SIZE - 1);
|
||||||
|
char *pointeur_alacon = NULL;
|
||||||
|
return pointeur_alacon + quelenfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Appends a bucket address to the list pointed by head
|
||||||
|
void bucket_list_append(struct bucket **head, struct bucket *elt)
|
||||||
|
{
|
||||||
|
struct bucket *list_elt = *head;
|
||||||
|
if (list_elt == NULL)
|
||||||
|
{
|
||||||
|
*head = elt;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (list_elt->next != NULL)
|
||||||
|
{
|
||||||
|
list_elt = list_elt->next;
|
||||||
|
}
|
||||||
|
list_elt->next = elt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes a bucket from the list pointed by head
|
||||||
|
void bucket_list_remove(struct bucket **head, struct bucket *elt)
|
||||||
|
{
|
||||||
|
struct bucket *list_elt = *head;
|
||||||
|
if (list_elt == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (*head == elt)
|
||||||
|
{
|
||||||
|
*head = elt->next;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (list_elt->next != NULL)
|
||||||
|
{
|
||||||
|
if (list_elt->next == elt)
|
||||||
|
{
|
||||||
|
list_elt->next = list_elt->next->next;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
list_elt = list_elt->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
malloc/src/helpers/helpers.h
Normal file
40
malloc/src/helpers/helpers.h
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef HELPERS_H
|
||||||
|
#define HELPERS_H
|
||||||
|
|
||||||
|
// #define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
#define MIN_BLOCK_SIZE 16
|
||||||
|
#define FREE_LIST_SIZE PAGE_SIZE / MIN_BLOCK_SIZE / sizeof(unsigned char)
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// Header
|
||||||
|
// Contains all informations about the concerned bucket
|
||||||
|
struct bucket
|
||||||
|
{
|
||||||
|
unsigned block_size;
|
||||||
|
unsigned char free_map[FREE_LIST_SIZE]; // Keeps track of allocations
|
||||||
|
// If block_size > MIN_BLOCK_SIZE
|
||||||
|
// It will use a consecutive
|
||||||
|
// representation
|
||||||
|
unsigned short alloc_blk_cnt; // Counts the number of allocated blocks
|
||||||
|
struct bucket *next;
|
||||||
|
size_t alloc_size;
|
||||||
|
|
||||||
|
unsigned short space1; //
|
||||||
|
unsigned int space2; // -> Both are used to align data on 16 bytes
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BUCKET_SIZE PAGE_SIZE - sizeof(struct bucket)
|
||||||
|
|
||||||
|
size_t s2p(size_t n);
|
||||||
|
int find_free_block(struct bucket *buck);
|
||||||
|
struct bucket *get_bucket(struct bucket *head, size_t size);
|
||||||
|
void *get_data_begin(struct bucket *biquette);
|
||||||
|
void *get_page_begin(void *ptr);
|
||||||
|
void *get_block(struct bucket *biquette, int block_number);
|
||||||
|
int get_block_number(struct bucket *biquette, void *block);
|
||||||
|
void bucket_list_append(struct bucket **head, struct bucket *elt);
|
||||||
|
void bucket_list_remove(struct bucket **head, struct bucket *elt);
|
||||||
|
|
||||||
|
#endif // ! HELPERS_H
|
||||||
82
malloc/src/malloc.c
Normal file
82
malloc/src/malloc.c
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "helpers/allocate.h"
|
||||||
|
#include "helpers/helpers.h"
|
||||||
|
|
||||||
|
struct bucket *head = NULL;
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void *malloc(size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Find adequate bucket
|
||||||
|
struct bucket *buck = get_bucket(head, size);
|
||||||
|
while (buck != NULL)
|
||||||
|
{
|
||||||
|
// Find adequate block
|
||||||
|
int block_number = find_free_block(buck);
|
||||||
|
if (block_number != -1)
|
||||||
|
return allocate_block(buck, block_number);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No free space -> loop
|
||||||
|
buck = get_bucket(buck->next, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buck = create_bucket(size);
|
||||||
|
bucket_list_append(&head, buck);
|
||||||
|
int first_free_buche = find_free_block(buck); // De noel (pas la mienne)
|
||||||
|
return allocate_block(buck, first_free_buche);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void free(void *ptr)
|
||||||
|
{
|
||||||
|
if (ptr == NULL)
|
||||||
|
return;
|
||||||
|
free_block(ptr, &head);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void *realloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return NULL;
|
||||||
|
if (ptr == NULL)
|
||||||
|
return malloc(size);
|
||||||
|
|
||||||
|
struct bucket *header = get_page_begin(ptr);
|
||||||
|
if (header == NULL)
|
||||||
|
return NULL; // Shouldn't get here
|
||||||
|
|
||||||
|
if (header->block_size >= size)
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void *new_ptr = malloc(size);
|
||||||
|
if (new_ptr == NULL)
|
||||||
|
return NULL;
|
||||||
|
memcpy(new_ptr, ptr, header->block_size);
|
||||||
|
free(ptr);
|
||||||
|
return new_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void *calloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
// Check overflow
|
||||||
|
size_t c;
|
||||||
|
if (__builtin_mul_overflow(nmemb, size, &c))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *res = malloc(c);
|
||||||
|
if (res == NULL)
|
||||||
|
return NULL;
|
||||||
|
memset(res, 0, nmemb * size);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
BIN
malloc/tests/corruptionproof
Executable file
BIN
malloc/tests/corruptionproof
Executable file
Binary file not shown.
BIN
malloc/tests/memoryfootprint
Executable file
BIN
malloc/tests/memoryfootprint
Executable file
Binary file not shown.
BIN
malloc/tests/speed
Executable file
BIN
malloc/tests/speed
Executable file
Binary file not shown.
24
malloc/tests/test-cmd.sh
Executable file
24
malloc/tests/test-cmd.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bi/sh
|
||||||
|
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m' # No color
|
||||||
|
|
||||||
|
echo Hello world!
|
||||||
|
|
||||||
|
check()
|
||||||
|
{
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo $RED ERROR $NC
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
LD_PRELOAD=./libmalloc.so ls 1> /dev/null
|
||||||
|
check
|
||||||
|
LD_PRELOAD=./libmalloc.so ip a 1> /dev/null
|
||||||
|
check
|
||||||
|
LD_PRELOAD=./libmalloc.so grep --help 1> /dev/null
|
||||||
|
check
|
||||||
|
LD_PRELOAD=./libmalloc.so find 1> /dev/null
|
||||||
|
check
|
||||||
|
LD_PRELOAD=./libmalloc.so tree 1> /dev/null
|
||||||
|
check
|
||||||
|
LD_PRELOAD=./libmalloc.so git status 1> /dev/null
|
||||||
25
malloc/tests/test.c
Normal file
25
malloc/tests/test.c
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
// #include <criterion/criterion.h>
|
||||||
|
// #include <criterion/new/assert.h>
|
||||||
|
|
||||||
|
// TestSuite(Main);
|
||||||
|
|
||||||
|
// Test(Main, test1)
|
||||||
|
// {
|
||||||
|
// int *i = malloc(16);
|
||||||
|
// cr_assert(i != NULL);
|
||||||
|
// }
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int *test = malloc(8);
|
||||||
|
void *tes2 = malloc(8);
|
||||||
|
void *tes3 = malloc(32);
|
||||||
|
void *tes4 = malloc(64);
|
||||||
|
void *tes5 = malloc(128);
|
||||||
|
void *tes6 = malloc(256);
|
||||||
|
void *tes7 = malloc(512);
|
||||||
|
void *tes8 = malloc(4096);
|
||||||
|
void *tes9 = malloc(95956);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue