I’m trying to learn C. Since I have already some familiarity with higher level languages (PHP, Javascript, Python) I feel most of the work I have to do involves learning how to replace structures which I would give for granted (say variable sized arrays) through the use of pointers, and manually managing memory. My problem is that I am a bit worried about playing with pointers.
Usually I try to experiment with other language features, but my problem is that a bad use of pointers could have unexpected results. In particular: is it possible – if I make a mistake – that I may corrupt memory segments that other programs are using, causing those programs to misbehave? Or will the operating system, (in my case various flavours of Ubuntu) prevent me to intefere with the memory assigned to different processes?
In the former case I guess it would be possible (though unlikely) that I may cause other programs to write bad data on the disk, corrupting some information I have on the hard drive. Or even worst (and even more unlikely, I guess) it could damage some hardware – for instance older monitors could be burned by software which would set an out of range refresh rate.
I know that probably my worries are not justified, but I would like to know how far the compiler/operating system will prevent me from doing dangerous operations when I make a mistake managing pointers.
Most modern, desktop-oriented operating systems (including Linux) use virtual memory to prevent a misbehaving program from disrupting other programs. Each process gets its own address space, and if you overflow a buffer or similarly misuse pointers, about the worst that can happen is you crash your process. You shouldn’t affect other processes in the system unless you’re writing a device driver or running as root (and if you’re running as root, you’d have to do something bad to a file another process is reading, etc… you still wouldn’t have direct access to another process’s memory).
In terms of catching errors before you make them, here are some rules to follow that can help you:
malloc, function arguments, etc.) for null before using them.freeing dynamically allocated memory, set the pointer to null. This should help you catch some dangling pointer or double-free errors. (Of course, if you’ve copied that pointer and stored it in other places in your code, you could still have these problems unless you’re careful.)