I'm trying to check for memory errors in this code.
#include <stdio.h>
#include <stdlib.h>
void test1() {
int i;
int max = 4;
int *a = (int *)malloc(max*sizeof(*a));
for (i=0; i<max; i++) {
a[i] = i*i;
printf ("%d %d\n", i, a[i]);
}
free(a); }
char *getString() {
char message[100] = "Hello World";
char *ret = message;
return ret; }
void test2() {
printf ("String : %s\n", getString()); }
int main() {
test1();
test2();
return 0; }
I know function test2() will have errors because getString() was returning a pointer to invalid memory location (because that memory was already freed when getString() finished because message[] array was allocated at stack i.e., a local variable). But valgrind is not showing me any error when i call only test2(). i.e. when I comment out the call to test1() in main().
==26998== Memcheck, a memory error detector
==26998== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==26998== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==26998== Command: ./a.out
==26998==
String :
==26998==
==26998== HEAP SUMMARY:
==26998== in use at exit: 0 bytes in 0 blocks
==26998== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==26998==
==26998== All heap blocks were freed -- no leaks are possible
==26998==
==26998== For lists of detected and suppressed errors, rerun with: -s
==26998== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
But when I let both test1() and test2() execute one after another I'm getting the desired error from valgrind.
==27200== Memcheck, a memory error detector
==27200== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==27200== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==27200== Command: ./a.out
==27200==
0 0
1 1
2 4
3 9
==27200== Conditional jump or move depends on uninitialised value(s)
==27200== at 0x48447B5: strlen (vg_replace_strmem.c:469)
==27200== by 0x48E3FD7: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200== by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200== by 0x1092C7: test2 (a.c:24)
==27200== by 0x1092E2: main (a.c:29)
==27200==
==27200== Conditional jump or move depends on uninitialised value(s)
==27200== at 0x48447C8: strlen (vg_replace_strmem.c:469)
==27200== by 0x48E3FD7: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200== by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200== by 0x1092C7: test2 (a.c:24)
==27200== by 0x1092E2: main (a.c:29)
==27200==
==27200== Conditional jump or move depends on uninitialised value(s)
==27200== at 0x48F8077: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200== by 0x48E3D32: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200== by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200== by 0x1092C7: test2 (a.c:24)
==27200== by 0x1092E2: main (a.c:29)
==27200==
==27200== Syscall param write(buf) points to uninitialised byte(s)
==27200== at 0x4966907: write (in /usr/lib/libc-2.33.so)
==27200== by 0x48F79CC: _IO_file_write@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200== by 0x48F6D45: new_do_write (in /usr/lib/libc-2.33.so)
==27200== by 0x48F8A68: _IO_do_write@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200== by 0x48F8015: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200== by 0x48E270F: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200== by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200== by 0x1092C7: test2 (a.c:24)
==27200== by 0x1092E2: main (a.c:29)
==27200== Address 0x4a46099 is 9 bytes inside a block of size 1,024 alloc'd
==27200== at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==27200== by 0x48EB563: _IO_file_doallocate (in /usr/lib/libc-2.33.so)
==27200== by 0x48F9DAF: _IO_doallocbuf (in /usr/lib/libc-2.33.so)
==27200== by 0x48F8F67: _IO_file_overflow@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200== by 0x48F8015: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200== by 0x48E2F55: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200== by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200== by 0x1091E0: test1 (a.c:11)
==27200== by 0x1092D8: main (a.c:28)
==27200==
String : Hello World
==27200==
==27200== HEAP SUMMARY:
==27200== in use at exit: 0 bytes in 0 blocks
==27200== total heap usage: 2 allocs, 2 frees, 1,040 bytes allocated
==27200==
==27200== All heap blocks were freed -- no leaks are possible
==27200==
==27200== Use --track-origins=yes to see where uninitialised values come from
==27200== For lists of detected and suppressed errors, rerun with: -s
==27200== ERROR SUMMARY: 24 errors from 4 contexts (suppressed: 0 from 0)
I also noticed one thing -
If I call test2() first and then test1() (ie. test2() is the first function that is called from main()), I DO NOT get any error from valgrind.
If I do not call test2() as the first function (i.e., if i call test1() before test2() and it doesn't matter if I call test1() again after that) I'm getting the error message.
So, why am I having this problem ? (I know the memory error in the code) I mean why is valgrind not showing me errors in certain cases ?
(I'm using Valgrind 3.17 on Manjaro Linux. Some of my classmates using Valgrind on Fedora and Redhat are also having same problem while some others using Ubuntu are not facing this problem.)