I can use more memory than how much I've alloc

2019-01-01 08:52发布

char *cp = (char *) malloc(1);
strcpy(cp, "123456789");
puts(cp);

output is "123456789" on both gcc (Linux) and Visual C++ Express, does that mean when there is free memory, I can actually use more than what I've allocated with malloc()?

and why malloc(0) doesn't cause runtime error?

Thanks.

标签: c
16条回答
零度萤火
2楼-- · 2019-01-01 09:24

malloc allocates the amount of memory you ask in heap and then return a pointer to void (void *) that can be cast to whatever you want.

It is responsibility of the programmer to use only the memory that has been allocate. Writing (and even reading in protected environment) where you are not supposed can cause all sort of random problems at execution time. If you are lucky your program crash immediately with an exception and you can quite easily find the bug and fix it. If you aren't lucky it will crash randomly or produce unexpected behaviors.

For the Murphy's Law, "Anything that can go wrong, will go wrong" and as a corollary of that, "It will go wrong at the right time, producing the most large amount of damage". It is sadly true. The only way to prevent that, is to avoid that in the language that you can actually do something like that.

Modern languages do not allow the programmer to do write in memory where he/she is not supposed (at least doing standard programming). That is how Java got a lot of its traction. I prefer C++ to C. You can still make damages using pointers but it is less likely. That is the reason why Smart Pointers are so popular.

In order to fix these kind of problems, a debug version of the malloc library can be handy. You need to call a check function periodically to sense if the memory was corrupted. When I used to work intensively on C/C++ at work, we used Rational Purify that in practice replace the standard malloc (new in C++) and free (delete in C++) and it is able to return quite accurate report on where the program did something it was not supposed. However you will never be sure 100% that you do not have any error in your code. If you have a condition that happen extremely rarely, when you execute the program you may not incur in that condition. It will eventually happen in production on the most busy day on the most sensitive data (according to Murphy's Law ;-)

查看更多
若你有天会懂
3楼-- · 2019-01-01 09:26

You should use new and delete operators in c++... And a safe pointer to control that operations doesn't reach the limit of the array allocated...

查看更多
步步皆殇っ
4楼-- · 2019-01-01 09:26

My answer is in responce to Why does printf not seg fault or produce garbage?

From

The C programming language by Denis Ritchie & Kernighan

 typedef long Align;    /* for alignment to long boundary */
   union header {         /* block header */
       struct {
           union header *ptr; /* next block if on free list */
           unsigned size;     /* size of this block */
       } s;
       Align x;           /* force alignment of blocks */
   };
   typedef union header Header;

The Align field is never used;it just forces each header to be aligned on a worst-case boundary. In malloc,the requested size in characters is rounded up to the proper number of header-sized units; the block that will be allocated contains one more unit, for the header itself, and this is the value recorded in the size field of the header. The pointer returned by malloc points at the free space, not at the header itself.

The user can do anything with the space requested, but if anything is written outside of the allocated space the list is likely to be scrambled.

   -----------------------------------------
   |        |     SIZE     |               |
   -----------------------------------------
     |        |
  points to   |-----address returned touser
   next free
   block
        -> a block returned by malloc 

In statement

char* test = malloc(1);

malloc() will try to search consecutive bytes from the heap section of RAM if requested bytes are available and it returns the address as below

 --------------------------------------------------------------
| free memory  | memory in size allocated for user |           |
----------------------------------------------------------------
                                                              0x100(assume address returned by malloc)
                                                              test

So when malloc(1) executed it won't allocate just 1 byte, it allocated some extra bytes to maintain above structure/heap table. you can find out how much actual memory allocated when you requested only 1 byte by printing test[-1] because just to before that block contain the size.

char* test = malloc(1);
printf("memory allocated in bytes = %d\n",test[-1]);
查看更多
孤独寂梦人
5楼-- · 2019-01-01 09:27

You get undefined behavior - anything can happen. Don't do it and don't speculate about whether it works. Maybe it corrupts memory and you don't see it immediately. Only access memory within the allocated block size.

查看更多
怪性笑人.
6楼-- · 2019-01-01 09:28

strcpy() doesn't check if the memory it's writing to is allocated. It just takes the destination address and writes the source character by character until it reaches the '\0'. So, if the destination memory allocated is smaller than the source, you just wrote over memory. This is a dangerous bug because it is very hard to track down.

puts() writes the string until it reaches '\0'.

My guess is that malloc(0) only returns NULL and not cause a run-time error.

查看更多
零度萤火
7楼-- · 2019-01-01 09:29

On most platforms you can not just allocate one byte. There is often also a bit of housekeeping done by malloc to remember the amount of allocated memory. This yields to the fact that you usually "allocate" memory rounded up to the next 4 or 8 bytes. But this is not a defined behaviour.

If you use a few bytes more you'll very likeley get an access violation.

查看更多
登录 后发表回答