check50
to check our work automaticallydebug50
and the debugger to step through our codehelp50
to make compilation errors more understandableprintf
to print out helpful information as our program runsstyle50
to check the style of our codevalgrind
valgrind
is a command-line tool that we can use to run our program and see if it has any memory leaks.
malloc
to ask the operating system for memory for our program, but we don’t call free
to mark it as free. Then, our program will use more and more memory as it runs, eventually slowing down or even crashing our entire computer.Let’s write a program called memory.c
to experiment a little bit:
#include <stdlib.h>
void f(void)
{
int *x = malloc(10 * sizeof(int));
x[10] = 0;
}
int main(void)
{
f();
return 0;
}
f
, that allocates memory for 10 integers, and using x
as a pointer to the address of the start of that memory. Then, we try to access the 11th integer with x[10]
(remember that pointers can act like arrays, since the memory we get is contiguous, or back-to-back).malloc
sometimes (but not always) gives us back a little more memory than we ask for, and we might get lucky and be able to access and use memory beyond the bounds of what we should have.We can run our program with valgrind ./memory
, and we see a lot printed out. But we do see one error message in particular, Invalid read of size 4
, followed by some pointers in hexadecimal. We see f (memory.c:15)
in the line immediately after, which tells us that this happened in line 15 of memory.c
in the function f
.
We can also use help50 valgrind ./memory
, which will distill the output for us, one error message at a time, and add additional clues to guide us.
If we fix our program to access x[9]
, then valgrind
onluy has 1 error message for us: 40 bytes in 1 blocks are definitely lost...
. And help50
tells us that we forgot to free memory we allocated with malloc
, so we should call free(x)
after we’re doing using it. Now, we have 0 errors.
Recall that we have some finite number of bytes in memory, and our operating system keeps track of which bytes are used by which program, which bytes are free, and indicates segmentation faults when we try to access memory that isn’t allocated to our program.
Rubber duck debugging is the process of explaining our code, step-by-step, to a rubber duck (or some other inanimate object), so we ourselves can understand it better and hopefully realize where we might have a bug or opportunity of improvement. Hopefully, this will be another simple, but powerful, tool for us to use.
最简单的办法:从头到尾说一遍;说的过程意识到犯错误
good software:脑海里出现过一次
string
is a synonym for char *
, a pointer to a character.main
function, live when our program is runningswap
function that didn’t work, when values were passed in directly, since it got its own copies of those values. Then, we saw a swap
function that took in the addresses of two variables, so those values could actually be swapped.