int CompiledDictionary::add_dictionary_level( const Dictionary::letter* s ) { const Dictionary::letter* l = s; int start = m_free_pointer - m_dict_tree; do { m_free_pointer->m_ch = l->m_ch; m_free_pointer->m_is_word = l->m_is_word; m_free_pointer->m_sibling_count = 0; m_free_pointer->m_child = 0; l = l->m_next; m_free_pointer++; m_used_space++; m_free_space--; allocate_new_space(); } while ( l != NULL ); m_free_pointer->m_ch = '\0'; m_free_pointer++; m_used_space++; m_free_space--; allocate_new_space(); l = s; int ltr = start; int sibling_count = 0; do { if ( l->m_child != NULL ) { // This is a tricky sequence of code, because add_dictionary_level // can allocate a new m_dict_tree, so it makes the assignment // to m_dict_tree[ltr] after the call to add_dictionary_level. int child = add_dictionary_level( l->m_child ); m_dict_tree[ltr].m_child = child; } l = l->m_next; ltr++; sibling_count++; } while ( l != NULL ); m_dict_tree[ start ].m_sibling_count = sibling_count; qsort( m_dict_tree + start, m_dict_tree[ start ].m_sibling_count, sizeof ( letter ), compare_letters ); return start; }
/** * Allocate memory block * * Allocates a block of size bytes of memory, returning a pointer to the * beginning of the block. The content of the newly allocated block of * memory is not initialized, remaining with indeterminate values. * * @param size * Size of the memory block, in bytes. * * @return * On success, a pointer to the memory block allocated by the function. * * The type of this pointer is always void*, which can be cast to the * desired type of data pointer in order to be dereferenceable. * * If the function failed to allocate the requested block of memory, * a null pointer is returned. * * @see http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/ */ void *malloc(size_t size) { if(size<=0) return NULL; if(free_list_ptr == NULL) free_list_ptr = free_list_init(); L( actual_size += size); size_t size_plus_dic = find_new_alloc_size(size); void *block_ptr = block_available(size_plus_dic); if (block_ptr == NULL) { /* Allocate new space from sbrk() */ block_ptr = allocate_new_space(size_plus_dic); D(printf("malloc(): find new space at loc %zu with length %zu, occupy:%d\n", (size_t)(block_ptr - heap_ptr),MDIC(block_ptr)->size, MDIC(block_ptr)->occupy )); // store the size_plus_dic into the block MDIC(block_ptr) -> occupy = true; free_list_delete(block_ptr , size2order( MDIC(block_ptr)->size )); // delete from free list. L( printf("size actual_size total_size: %zu %zu %zu\n",size,actual_size,total_size) ); return block_ptr + sizeof(mem_dic); } else { if (MDIC(block_ptr)->size > size_plus_dic) block_ptr = split_block(block_ptr,size_plus_dic); if ( !block_ptr || MDIC(block_ptr)->size != size_plus_dic){ D( printf("Error in malloc(): size after split cannot match\n") ); return NULL; } /* Assign the size to the block, split the block if necessary */ D( printf("malloc(): find old space at loc %zu with length %zu, occupy:%d\n", (size_t)(block_ptr - heap_ptr),MDIC(block_ptr)->size, MDIC(block_ptr)->occupy ) ); MDIC(block_ptr) -> occupy = true; free_list_delete(block_ptr,size2order( MDIC(block_ptr)->size )); L( printf("size actual_size total_size: %zu %zu %zu\n",size,actual_size,total_size) ); return block_ptr + sizeof(mem_dic); } return NULL; }