Reputation: 355
I have a doubt in malloc and realloc function, When I am using the malloc function for allocating the memory for the character pointer 10 Bytes. But when I am assigning the value for that character pointer, it takes more than 10 bytes if I try to assign. How it is possible.
For example:
main()
{
char *ptr;
ptr=malloc(10*sizeof(char));
gets("%s",ptr);
printf("The String is :%s",ptr);
}
Sample Output:
$./a.out
hello world this is for testing
The String is :hello world this is for testing
Now look at the output the number of characters are more than 10 bytes. How this is possible, I need clear explanation. Thanks in Advance.
Upvotes: 3
Views: 1384
Reputation: 153338
OP: ... number of characters are more than 10 bytes. How this is possible?
A: Writing outside allocated memory as done by gets()
is undefined behavior - UB. UB ranges from working just as you want to crash-and-burn.
The real issue is not the regrettable use of gets()
, but the idea that C language should prevent memory access mis-use. C does not prevent it. The code should prevent it. C is not a language with lots of behind-the-scenes protection. If writing to ptr[10]
is bad, don't do it. Don't call functions that might do it such as gets()
. Like many aspects of life - practice safe computing.
C gives you lots of rope to do all sorts of things including enough rope to hang yourself.
Upvotes: 0
Reputation: 105992
That's why using gets
is an evil thing. Use fgets
instead.
malloc
has nothing to do with it.
Admittedly, rationale would be useful, yes? For one thing,
gets()
doesn't allow you to specify the length of the buffer to store the string in. This would allow people to keep entering data past the end of your buffer, and believe me, this would be Bad News.
First, let's look at the prototype for this function:
#include <stdio.h>
char *gets(char *s);
You can see that the one and only parameter is a char
pointer. So then, if we make an array like this:
char buf[100];
we could pass it to gets()
like so:
gets(buf)
So far, so good. Or so it seems... but really our problem has already begun. gets()
has only received the name of the array (a pointer), it does not know how big the array is, and it is impossible to determine this from the pointer alone. When the user enters their text, gets()
will read all available data into the array, this will be fine if the user is sensible and enters less than 99 bytes. However, if they enter more than 99, gets()
will not stop writing at the end of the array. Instead, it continues writing past the end and into memory it doesn't own.
This problem may manifest itself in a number of ways:
No visible affect what-so-ever
Immediate program termination (a crash)
Termination at a later point in the programs life time (maybe 1 second later, maybe 15 days later)
Termination of another, unrelated program
Incorrect program behavior and/or calculation ... and the list goes on. This is the problem with "buffer overflow" bugs, you just can't tell when and how they'll bite you.
Upvotes: 6
Reputation: 222312
malloc
reserves memory for your use. The rules are that you are permitted to use memory allocated this way and in other ways (as by defining automatic or static objects) and you are not permitted to use memory not allocated for your use.
However, malloc
and the operating system do not completely enforce these rules. The obligation to obey them belongs to you, not to malloc
or the operating system.
General-purpose operating systems have memory protection that prevents one process from reading or altering the memory of another process without permission. It does not prevent one process from reading or altering its own memory in improper ways. When you access bytes that you are not supposed to, there is no mechanism that always prevents this. The memory is there, and you can access it, but you should not.
gets
is a badly designed routine, because it will write any amount of memory if the input line is long enough. This means you have no way to prevent it from writing more memory than you have allocated. You should use fgets
instead. It has a parameter that limits the amount of memory it may write.
General-purpose operating systems allocate memory in chunks known as pages. The size of a page might be 4096 bytes. When malloc
allocates memory for you, the smallest size it can get from the operating system is one page. When you ask for ten bytes, malloc
will get a page, if necessary, select ten bytes in it, keep records that a small portion of the page has been allocated but the rest is available for other use, and return a pointer to the ten bytes to you. When you do further allocations, malloc
might allocate additional bytes from the same page.
When you overrun the bytes that have been allocated to you, you are violating the rules. If no other part of your process is using those bytes, you might get away with this violation. But you might alter data that malloc
is using to keep track of allocations, you might alter data that is part of a separate allocation of memory, or you might, if you go far enough, alter data that is in a separate page completely and is in use by a completely different part of your program.
A general-purpose operating system does provide some protection against improper use of memory within your process. If you attempt to access pages that are not mapped in your virtual address space or you attempt to modify pages that are marked read-only, a fault will be triggered, and your process will be interrupted. However, this protection only applies at a page level, and it does not protect against you incorrectly using the memory that is allocated to your process.
Upvotes: 2
Reputation: 1768
The malloc will reserve 10 bytes (in your case assuming the char have 1 byte) and will return the start point of the reserved area.
You do a gets
, so it get the text you typed and write using your pointer.
Windows/Mac os x/ Unix (Advances OS'S) have protected memory.
That means, when you do a malloc/new the OS reserve that memory area for your program. IF another program tries to write in that area an segmentation fault happens because you wrote on an area that you should not write.
You reserved 10 bytes. IF the byte 11, 12, 13, 14 are not yet reserved for another program it will not crash, if it is your program will access an protected area and crash.
Upvotes: 1
Reputation: 1305
You just got an undefined behavior. (More information here)
Use fgets and not gets !
Upvotes: 2