Question

Here' my piece of code:

#include <stdio.h>
#include<stdlib.h>

struct student{
char *name;
};

int main()
{
        struct student s;

        s.name = malloc(sizeof(char *)); // I hope this is the right way...

        printf("Name: ");    
        scanf("%[^\n]", s.name);


        printf("You Entered: \n\n");

        printf("%s\n", s.name);

        free(s.name);   // This will cause my code to break
}

All I know is that dynamic allocation on the 'heap' needs to be freed.

My question is, when I run the program, sometimes the code runs successfully. i.e.

./struct
Name: Thisis Myname
You Entered: 

Thisis Myname

I tried reading this

I've concluded that I'm trying to double-free a piece of memory i.e. I'm trying to free a piece of memory that is already free? (hope I'm correct here. If yes, what could be the Security Implications of a double-free?)

While it fails sometimes as its supposed to:

./struct
Name: CrazyFishMotorhead Rider
You Entered: 

CrazyFishMotorhead Rider
*** glibc detected *** ./struct: free(): invalid next size (fast): 0x08adb008 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b161)[0xb7612161]
/lib/tls/i686/cmov/libc.so.6(+0x6c9b8)[0xb76139b8]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xb7616a9d]
./struct[0x8048533]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb75bdbd6]
./struct[0x8048441]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 288098     /root/struct
08049000-0804a000 r--p 00000000 08:01 288098     /root/struct
0804a000-0804b000 rw-p 00001000 08:01 288098     /root/struct
08adb000-08afc000 rw-p 00000000 00:00 0          [heap]
b7400000-b7421000 rw-p 00000000 00:00 0 
b7421000-b7500000 ---p 00000000 00:00 0 
b7575000-b7592000 r-xp 00000000 08:01 788956     /lib/libgcc_s.so.1
b7592000-b7593000 r--p 0001c000 08:01 788956     /lib/libgcc_s.so.1
b7593000-b7594000 rw-p 0001d000 08:01 788956     /lib/libgcc_s.so.1
b75a6000-b75a7000 rw-p 00000000 00:00 0 
b75a7000-b76fa000 r-xp 00000000 08:01 920678     /lib/tls/i686/cmov/libc-2.11.1.so
b76fa000-b76fc000 r--p 00153000 08:01 920678     /lib/tls/i686/cmov/libc-2.11.1.so
b76fc000-b76fd000 rw-p 00155000 08:01 920678     /lib/tls/i686/cmov/libc-2.11.1.so
b76fd000-b7700000 rw-p 00000000 00:00 0 
b7710000-b7714000 rw-p 00000000 00:00 0 
b7714000-b7715000 r-xp 00000000 00:00 0          [vdso]
b7715000-b7730000 r-xp 00000000 08:01 788898     /lib/ld-2.11.1.so
b7730000-b7731000 r--p 0001a000 08:01 788898     /lib/ld-2.11.1.so
b7731000-b7732000 rw-p 0001b000 08:01 788898     /lib/ld-2.11.1.so
bffd5000-bfff6000 rw-p 00000000 00:00 0          [stack]
Aborted

So why is it that my code does work sometimes? i.e. the compiler is not able to detect at times that I'm trying to free an already freed memory.

Has it got to do something with my stack/heap size?

Was it helpful?

Solution

 s.name = malloc(sizeof(char *)); // I hope this is the right way...

its not the right way, it allocates memory the size of a char pointer, ( 4 bytes most likely )

you want something like ...

s.name = malloc(sizeof(char)*1000);

where 1000 is whatever maximum length of input you are expecting.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top