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

int main(void)
{
        char* a = malloc(2 * sizeof(char));
        a[0] = '0';
        a[1] = '1';
        a[2] = '2';
        a[3] = '4';
        printf("%s\n", a);
}

Hi, I am trying to understand what the malloc function does. From what I learnt the above code should return an error because I am declaring just 2 bytes of memory to the string 'a' .But it doesn't displays any error. Please explain why it does so.

Lokesh
  • 2,842
  • 7
  • 32
  • 47
  • 3
    it shows you undefined behaviour. – Jayesh Bhoi Sep 11 '14 at 10:23
  • What shows undefined behaviour? Kindly explain. – Lokesh Sep 11 '14 at 10:27
  • 2
    Don't confuse *observed* behavior with *defined* behavior. Your program is ill-formed. As such, it can exhibit almost anything, and may (if you're unlucky enough) even *work*. – WhozCraig Sep 11 '14 at 10:28
  • 1
    It is undefined behaviour - which basically means it might do anything. "Seeming to work" is a subset of "anything". – user253751 Sep 11 '14 at 10:34
  • 1
    And many would say that it's actually worse when it seems to work - it might stay that way for years, then suddenly stop working when you change something completely unrelated, and make you waste a week finding out why it suddenly stopped working. – user253751 Sep 11 '14 at 10:35
  • One more thing please. Is it better to create your string with more than one characters than you actually need in that string to store so that you can initialize that last character to '\0'? – Lokesh Sep 11 '14 at 11:10
  • @Lokesh if it doesn't end with \0 then it's not a string - it's just a normal array of characters. A string is an array of characters ending in \0. – user253751 Sep 11 '14 at 20:53
  • Thanks for your response @immibis. You said string is an array of characters ending in \0. Does \0 gets automatically inserted when I alloc some memory for it or not. If not then how do I get a result limited to the number of values I have initialized. For example I gave 4 bytes to a string and define index 0 of that string with 'a' and when I print the result I only get 'a' not what stored in other index of the string. (Assume I have not initialized other indexes of the string.) How does this happen? – Lokesh Sep 13 '14 at 14:13
  • @Lokesh they might just happen to be 0 already. It's like when you store more stuff than you allocated - it's *allowed* to work sometimes, then randomly stop working later. – user253751 Sep 13 '14 at 22:35

3 Answers3

5

It is undefined behaviour to access allocated memory beyond its end. In other words, it may crash your application or may work for years as expected.

malloc() typically allocates memory in multiples of minimum alignment sizeof(void*), so that sometimes you can access a few bytes past the required size with no negative consequences.

A couple of notable examples of undefined behaviour related to heap memory going unnoticed for years:

The poisoned NUL byte, 2014 edition:

An odd malloc() size will always result in an off-by-one off the end being harmless, due to malloc() minimum alignment being sizeof(void*).

How Microsoft Lost the API War:

I first heard about this from one of the developers of the hit game SimCity, who told me that there was a critical bug in his application: it used memory right after freeing it, a major no-no that happened to work OK on DOS but would not work under Windows where memory that is freed is likely to be snatched up by another running application right away. The testers on the Windows team were going through various popular applications, testing them to make sure they worked OK, but SimCity kept crashing. They reported this to the Windows developers, who disassembled SimCity, stepped through it in a debugger, found the bug, and added special code that checked if SimCity was running, and if it did, ran the memory allocator in a special mode in which you could still use memory after freeing it.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
1

This is undefined behavior, bound checking is not done in C.

ani627
  • 5,578
  • 8
  • 39
  • 45
1

Code syntax is correct, malloc usage and pointer usage, but compiler does not perform static code analysis to check if that usage combination makes sense.

Mateusz Drost
  • 1,171
  • 10
  • 23