I personally like the concept of pointers because they are very useful and efficient in many ways, such as in a tree data structure. Furthermore, it helps me better understand how the code works at the low level in more details; it is my belief that a good programmer should know both the low level and high level sides of a system.
At the same time, I admit that one needs to be very careful with pointers because improper use of pointers will lead to a disaster. Here, I would like to give an example of such improper use of a pointer that will lead to memory leak.
People often interchangeably use pointers and arrays. Below is example1.c code:
The code compiles with no error or warning:
$ gcc example1.c -o example1 && ./example1
pppp
aaaa
OK. As you may have expected, the string can be either a pointer or an array; there seems nothing wrong with this. So, is it true that you can interchangeably use the pointer or the array to define a string? The answer is NO.
In the above example, str1 is a pointer to "pppp", which is allocated outside the function main stack. In other words, the variable str1 is a local variable in main, but it points to "pppp" that is saved in the memory outside the main's scope. On the other hand, str2 is a local variable array which saves the string value "aaaa".
Let's examine the memory using gdb. Before that, we need to compile the source with -g option in gcc to supply symbols:
$ gcc -g example1.c -o example1
Next, run gdb and examine str1 and str2:
$ gdb -q example1
Reading symbols from example1...done.
(gdb) b 6
Breakpoint 1 at 0x80484b3: file example1.c, line 6.
(gdb) r
Starting program: /home/linuxnme/Documents/
pppp
aaaa
Let's examine the memory content of &str1
(gdb) x/wx &str1
0xbffff570: 0x08048560
(gdb) x/s str1
0x8048560: "pppp"
Let's examine &str2 now.
(gdb) x/wx &str2
0xbffff577: 0x61616161
(gdb) x/s &str2
0xbffff577: "aaaa"
Can you tell the difference now? Let's quit gdb with
(gdb) q
(gdb) q
Quit anyway? (y or n) y
Now in order to examine memory leakage, let's consider example2.c code:
Let's compile and run it. When compiling the code, your compiler should warn you that the function returns the address of the local variable.
$ gcc example2.c -o example2 && ./example2
?
pppp
As you can see, when a string is defined as an array in a local function, it is saved in the function's stack and therefore it is completely cleared out when the function returns. However, if a string is defined as a pointer, then the string is saved outside the function's scope, and therefore it will remain in the memory. This is the memory leak in the program. Here, it is only a 5-byte memory leak, but it can get worse very quickly if the function is called multiple times during its run. Although I only demonstrated this with a char string, it could be of any data types including structures or classes.
So, the main lesson here is never define anything directly from a pointer, especially in a local function because it will lead to memory leak.
No comments:
Post a Comment