Week02 Lab Notes
ex1
Use of ++ and -- in array indexing.
Try to be careful abou that.
If you use it and cannot explain, it might be a trouble.
For example, if you use the following statement in your pop.
int val = ps->data[--size]
My suggestion is to STRONGLY avoid using these misleading expressions for beginners, especially in your Q&A.
strcmp
int strcmp (const char* str1, const char* str2);
Are there any alternatives to this beautiful code ?
if (strcmp(token, "+") == 0 || strcmp(token, "-") == 0 ||
strcmp(token, "*") == 0 || strcmp(token, "/") == 0)
{
int b = ps->pop(ps);
int a = ps->pop(ps);
if (strcmp(token, "+") == 0) ps->push(ps, a + b);
else if (strcmp(token, "-") == 0) ps->push(ps, a - b);
else if (strcmp(token, "*") == 0) ps->push(ps, a * b);
else if (strcmp(token, "/") == 0) ps->push(ps, a / b);
}
else
{
ps->push(ps, atoi(token)); // Convert string to int and push onto stack
}
or this
while (NULL != token)
{
if (strcmp(token, "+") == 0) {
int num1 = ps->pop(ps);
int num2 = ps->pop(ps);
ps->push(ps, num2+num1);
}
else if (strcmp(token, "-") == 0) {
int num1 = ps->pop(ps);
int num2 = ps->pop(ps);
ps->push(ps, num2-num1);
}
else if (strcmp(token, "*") == 0) {
int num1 = ps->pop(ps);
int num2 = ps->pop(ps);
ps->push(ps, num2*num1);
}
else if (strcmp(token, "/") == 0) {
int num1 = ps->pop(ps);
int num2 = ps->pop(ps);
ps->push(ps, num2/num1);
}
else {
ps->push(ps, atoi(token));
}
// get next token
token = strtok(NULL, delim);
}
ex2
check if a pointer is NULL
if (!chunk) return NULL;
if (ppool && *ppool)
cast void * to char * for pointer arithmetic
if ((char *)pchunk1->start + pchunk1->size == (char *)next->start)
Although (void *) and (char *) can be both equivalently cast to any other pointer type, it is only legal to perform pointer arithmetic on a (char *) and not with (void *) if you want to comply with Standard C.
When to use pointers of pointers ?
Compare
void change_head_pp(Node** _pphead, Node * _pnode)
{
* pphead = node;
}
and
void change_head_p(Node* _phead, Node * _pnode)
{
phead = node;
}
With the following code, which function changes the value of list_head ?
Node * phead = new_node();
Node * pnode = new_node();
change_head_p(phead, pnode);
change_head_pp(&phead, pnode);

Conclusion
If you want to change what a pointer points to or free the memory a pointer points to by use of a function, you need to input the address of that pointer (pointer to pointer) to the function.
How does this beautiful code work ?
void *_pool_malloc(Pool *self, size_t size)
{
Chunk *chunk = find_chunk_by_size(self->unused, size);
if (!chunk) return NULL;
remove_chunk_from_list(chunk);
if (chunk->size > size)
{
Chunk *new_chunk_node = new_chunk((char *)chunk->start + size,
chunk->size - size); // Renamed variable
insert_chunk_to_list(self->unused, new_chunk_node);
chunk->size = size;
}
insert_chunk_to_list(self->used, chunk);
return chunk->start;
}
Further Readings on Memory Management
Java
Java uses a VM and Garbage Collectioin which uses alogoirthms such as Mark-and-Sweep.
JVM memory structure
Mark and Sweep
Rust
uses scope and single ownership
Linux
Linux is an operating system whose memory management (MM) needs to take care of processes and virtual memories ( memory mapped to the hard disk) and paging. MM is the most complex and important part of Linux Kernel. It is definitely much more complex than our ex02.
But if you have learned decent knowledge of Linux MM, you will be an export on C and embedded systems.
Last updated