-2

I was experimenting with the pointers. I initially, created a pointer to a character and allocated a size of 2 bytes the pointer. Then I ran loop till 1000 assigning some values. When I try to print the String it gives me a whole set values that have been assigned.

#include <iostream>
#include <string.h>

using namespace std;


int main()
{
    char *a = (char *)malloc(2);
    for (int i=0;i<10;i++)
       a[i]='a';
    cout<<a<<"\t"<<strlen(a)<<"\n";
    return 0;
}

The output will be as follows

aaaaaaaaaa    10

I ran the same code in both C and C++. They are giving me the same result.

As of a first thought, since I used the pointers, a[3] mean *(&a + 3): which would explain why I am able to assign a value to that location. But, even when I allocated only two bytes of memory to String, Why is my string length being varied? Why is that the compiler behaving in a different manner? What goes behind the screen?

OS: OS X 10.10.0 compiler: gcc || g++ Architecture: 64-bit Architecture

Edit1: It is not about the seg fault.

Edit2: If it is because the strlen reads until it encounters a null terminator. I haven't declared it at the end of the string.

iMinion
  • 11
  • 3
  • Well, it is not about why it doesn't crash! It is about why the string is being altered in size? – iMinion Nov 07 '14 at 03:43
  • `strlen` just counts successive characters (bytes) until it encounters a null terminator. It doesn't have any knowledge of malloc or what size of space you allocated for anything. So because you wrote 10 'a' in successive areas of memory, `strlen` will count to at least 10. The size of memory that was allocated by `malloc` never changed. You're just doing things that write and read beyond the end of memory. – TheUndeadFish Nov 07 '14 at 05:38
  • @TheUndeadFish in C or C++, we explicitly declare the end of a string. Which will be contradictory. – iMinion Nov 07 '14 at 12:57
  • I don't understand what you mean by that. You allocated memory of a particular size but then wrote past that. C and C++ don't prevent you from doing such things. Really, the entire memory space of a program can be thought of as a single large array. C/C++ impose a set of rules and ideas on top of that, however they also expect you (the programmer) to follow those rules. When you break those rules (such as by writing past the end of allocated memory), then you can end up with unexpected results. – TheUndeadFish Nov 08 '14 at 00:55
  • @TheUndeadFish Thanks for getting back. Just to leave to the rules of compiler! I believe there is more to it. I can't take in that. Thank You Pal. – iMinion Nov 09 '14 at 10:13
  • @TheUndeadFish If strlen reads until the very end of the null terminator, we explicitly declare the null terminator. And in the above code I haven't declared the full terminator. Still it says the length is 10 and prints the string with 10 characters. – iMinion Nov 11 '14 at 03:47
  • A null terminator is just a byte in memory with a value of zero. So strlen keeps reading until it finds one. Apparently in your specific example, there's a zero byte immediately after the last 'a' that you wrote. However there is no guarantee that this will always be the case. If you change the test scenario, you might see a larger length result and "garbage" in the output because there were additional non-zero bytes. This is one of the possibilities of undefined behavior - sometimes it _appears_ to work as you expect even though the code is still not correct. – TheUndeadFish Nov 11 '14 at 23:12

1 Answers1

0

This code is have problem in memory usage. Only 2 bytes of memory is allocated but 10 byes is used. This will cause memory corruption. Then the behavior is undefined.

  for (int i=0;i<1 /*10*/;i++)

In your case the max i value can be 1 not 10. The remaining 1 bye is for \0 character.

mahendiran.b
  • 1,315
  • 7
  • 13
  • There wasn't any set fault when I tried it out. Seg fault is being generated when I use the MAX value to be some where around INT_MAX(I tried only for this one). – iMinion Nov 07 '14 at 03:03
  • @iMinion Who said anything about a seg fault? There is no guarantee you will be saved by a segmentation fault when you start using undefined behavior. – Red Alert Nov 07 '14 at 03:20
  • @RedAlert I'll agree with you. I get the point that the behaviour is undefined. I would like to know what is going is background.[link](http://stackoverflow.com/questions/6452959/why-doesnt-my-program-crash-when-i-write-past-the-end-of-an-array). The answer explains when a memory Corruption is done. Which will be contradictory to think that the behaviour is undefined. – iMinion Nov 07 '14 at 03:29
  • How could memory corruption possibly be well defined? You have no idea whose memory you are modifying with this code. What's going on in the background is simple, you are writing to memory not allocated to `a`. What happens as a result of that is undefined. – Red Alert Nov 07 '14 at 03:30
  • @RedAlert The question I have is why is it happening so?How is a C++ compiler working in back ground? Even when we know that it is undefined why is the result different? – iMinion Nov 07 '14 at 03:40
  • @iMinion It's happening because you allocate 2 bytes to `a` and attempt to modify bytes beyond that. The specific implementation details of the compiler are irrelevant. – Red Alert Nov 07 '14 at 03:47