0
 #include<stdio.h>
 #include<cs50.h>
 int main(void)
 {
     char* s= malloc(sizeof(char)*5)); //allocating 5 bytes
     fgets(s,6,stdin);  //allocating 5 bytes for hello and 1 byte for '\0'
     printf("%s",s);
     return 0;
 }

When I give input as hello, the output shows hello.

But the thing I don't understand is even if I didn't malloc 1 byte for '\0', the code doesn't show any error.

0

You're getting errors, they're just not breaking your program because you're lucky.

If you run valgrind on that code, it will show you an invalid write of one byte (the '\0') to an address that you shouldn't be writing to (that is, the byte past the 5 bytes you've malloc'ed).

You'll also get an invalid read of one byte when you call that printf.

In short, you shouldn't do what you've done. This didn't break your code this time, but it's not correct and could cause problems in the future.

Here's the valgrind's output:

==12350== Memcheck, a memory error detector
==12350== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==12350== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==12350== Command: ./ctest
==12350== 
hello
==12350== Invalid write of size 1
==12350==    at 0x5E2733A: fgets (iofgets.c:64)
==12350==    by 0x42D536: main (ctest.c:7)
==12350==  Address 0x617e045 is 0 bytes after a block of size 5 alloc'd
==12350==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12350==    by 0x42D51C: main (ctest.c:6)
==12350== 
==12350== Invalid read of size 1
==12350==    at 0x5E04A03: vfprintf (vfprintf.c:1661)
==12350==    by 0x5E07F30: buffered_vfprintf (vfprintf.c:2356)
==12350==    by 0x5E02EAD: vfprintf (vfprintf.c:1313)
==12350==    by 0x5E0D498: printf (printf.c:33)
==12350==    by 0x42D54F: main (ctest.c:8)
==12350==  Address 0x617e045 is 0 bytes after a block of size 5 alloc'd
==12350==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12350==    by 0x42D51C: main (ctest.c:6)
==12350== 
hello==12350== 
==12350== HEAP SUMMARY:
==12350==     in use at exit: 5 bytes in 1 blocks
==12350==   total heap usage: 1 allocs, 0 frees, 5 bytes allocated
==12350== 
==12350== 5 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12350==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12350==    by 0x42D51C: main (ctest.c:6)
==12350== 
==12350== LEAK SUMMARY:
==12350==    definitely lost: 5 bytes in 1 blocks
==12350==    indirectly lost: 0 bytes in 0 blocks
==12350==      possibly lost: 0 bytes in 0 blocks
==12350==    still reachable: 0 bytes in 0 blocks
==12350==         suppressed: 0 bytes in 0 blocks
==12350== 
==12350== For counts of detected and suppressed errors, rerun with: -v
==12350== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

If you look closely you'll see:

==12350== Invalid write of size 1
==12350==    at 0x5E2733A: fgets (iofgets.c:64)
==12350==    by 0x42D536: main (ctest.c:7)

And:

==12350== Invalid read of size 1
==12350==    at 0x5E04A03: vfprintf (vfprintf.c:1661)
==12350==    by 0x5E07F30: buffered_vfprintf (vfprintf.c:2356)
==12350==    by 0x5E02EAD: vfprintf (vfprintf.c:1313)
==12350==    by 0x5E0D498: printf (printf.c:33)
==12350==    by 0x42D54F: main (ctest.c:8)
6
  • Oh yes.I didn't even check with valgrind this time.Thanks for pointing out the mistake, Yuri.Also I didn't even free the pointer itself. – qwerty Dec 2 '16 at 18:16
  • Hey, if I use char a[n];and use n=getint() to get n at runtime ,is the memory allocated at runtime like malloc().? – qwerty Dec 3 '16 at 13:52
  • Those are called variable length arrays. You can read more about them here: drdobbs.com/the-new-cwhy-variable-length-arrays/184401444 – Yuri Laguardia Dec 3 '16 at 15:00
  • Thanks ,that was informative.According to the link, you've sent,VLA's are simpler and better than malloc.So why do we use malloc?Is it because they can be realloced to increase the length of array? – qwerty Dec 3 '16 at 15:49
  • Exactly. You can set a VLA length at runtime, but you can't resize if you need it bigger later. But with malloc you can always realloc. – Yuri Laguardia Dec 3 '16 at 17:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .