as vart pointed out, you're lucky. You're stepping past memory you've allocated (or possibly memory you have allocated) and into 'the unknown'. And I would say hat you're unlucky you didn't get a crash.
Read the FAQ, and listen to what is said.
Printable View
as vart pointed out, you're lucky. You're stepping past memory you've allocated (or possibly memory you have allocated) and into 'the unknown'. And I would say hat you're unlucky you didn't get a crash.
Read the FAQ, and listen to what is said.
> it does not give error. What is the problem.
That's just dumb luck on your part.
Sooner or later, the next malloc() or free() call for instance, it would all go pear shaped in spectacular fashion, and your question would have morphed into "why does my foo() call fail here?".
Because C has little or no run-time checks, there is no failure at the point the mistake is made, only at the point where it is first noticed. This "cause and effect" really confuses a lot of newbies into looking in the wrong place.
I am praying on you SALEM , thank you for your understanding...
Also Zac7 we disscussed this before. If you wont point another thing , just dont write. I want you to have a look at your last post. What did you do?Nothing. ALL you said is "Vart is true , see FAQ" .Maybe all you always say is see FAQ. I respect all of your knowledge . But sometimes you dont respect newbies. You treat them like a seperated low level learner , and avoid helping them , you dont even read what people say. I dont care what you do or how you treat me , I just appeal , DO NOT waste my time , you do not look bigger when you post empty posts..
Well, it will crash EVENTUALLY if you input a long enough string - unless of course the compiler generated some "memory protection code" or some such.
The case here is that you don't really know what you're overwriting, and how far that is from anything "important" that will make the code crash. Imagine that malloc internally works like this:
Imagine also that your call to malloc is the first one (so list_of_blocks is NULL), we grab a 4MB block of memory, and split it into smaller blocks. So the next "bad memory address" is 4MB from where you got your memory...Code:void *malloc(size_t size) {
if (list_of_blocks == NULL) {
list_of_blocks = allocate_block(MEGABYTES * 4);
block = split_block(list_of_blocks, size);
return block;
}
Under other circumstances, it may be much closer to the end.
If you're using the keyboard to type into the gets, it may take quite some time to type megabytes of data... [keyboard repeat rate is something like 10 keys per second if you hold a key down. 4M / 10 = 400000s = 100+ hours...]
Now of course, I just made that malloc function up - but I do know that malloc at least SOMETIMES allocates large chunks of memory and then splits it into smaller pieces, because that's one way to implement a malloc function - it is generally "expensive" to ask the operating system for memory, so you don't want to do that every time some user wants ten or a hundred bytes - particularly since most OS's don't support allocating small blocks of memory, only in multiples of 4K or some such. So to spread the cost of asking for memory from the OS, malloc "guesses" what the app needs, and then splits it to smaller chunks as needed.
Each combination of OS and C-library will implement malloc slightly differently, but the general principle is similar in most cases.
--
Mats
All I wanted was this , matsp , thank you a lot . Bless you =)
Evidently you don't read posts, I pointed out what exactly you were doing. Please don't be so rude, it hurts my feelings ;)Quote:
Also Zac7 we disscussed this before. If you wont point another thing , just dont write.
Heyyy, I didnt mean to be rude . It is cool.
Building on what the others had said, the size of some object really depends how it was allocated, and where in the code you decide to ask. sizeof is a special function provided by the compiler that computes the size of an object on a function's stack.Code:#include <stdio.h>
#include <stdlib.h>
unsigned long foo( int (*p_stack)[5] )
{
return sizeof p_stack;
}
int main( void )
{
int p_auto[] = { 0, 1, 2, 3, 4, };
int *p_heap = malloc( sizeof *p_heap * 5 );
if ( p_heap )
{
printf( "sizeof p_auto = %lu\n", sizeof p_auto );
printf( "sizeof p_auto[0] = %lu\n", sizeof p_auto[0] );
printf( "sizeof p_auto / sizeof p_auto[0] = %lu ;)\n", sizeof p_auto / sizeof p_auto[0] );
printf( "sizeof p_heap = %lu\n", sizeof p_heap );
printf( "sizeof *p_heap = %lu\n", sizeof *p_heap );
printf( "sizeof p_stack = %lu\n", foo( &p_auto ) );
free( p_heap );
p_heap = NULL;
}
return 0;
}
/**
* sizeof p_auto = 20
* sizeof p_auto[0] = 4
* sizeof p_auto / sizeof p_auto[0] = 5 ;)
* sizeof p_heap = 4
* sizeof *p_heap = 4
* sizeof p_stack = 4
*/
And you will notice that pointers often occupy the stack in a function; ones like p_heap might be 4 or longer on other systems. The size of a pointer is the byte-width RAM requires to store a memory address. The size of an array on the other hand is much different. The array uses all the memory it needs from the function stack. Therefore we can conclude that the size of p_auto is accurate.
So, what to learn from all of this: keep a variable handy that knows the length of a pointed to array, because it is hard to tell otherwise. If you need to know the size of a pointed to object (like int), dereference the pointer first.