-3
#include<stdio.h>
#include<iostream>
#include<cstring>
using namespace std;
int main(void)
{
    char a[10]="Rosewater";
    char b[3];

    int i=0;
    for(i=0;i<5;i++)
    {
        b[i]=a[i]; //1. does not throw an error
    }
    printf("%s\n%s\n",a,b);
}

Output:

ewsewater        // value of a also changed

Rosewsewater      // unclear output
Ahmad Khan
  • 2,655
  • 19
  • 25
  • 3
    You have undefined behavior. – Rakete1111 Sep 18 '16 at 10:43
  • 1
    Your code writes past the end of `b`, thus causing undefined behavior. Undefined behavior may cause an error, but it does not have to. – Sergey Kalinichenko Sep 18 '16 at 10:44
  • yeah i get that.. but how is it changing the value of string a? That should have been left as it is.. – Sumit Kumar Sep 18 '16 at 10:47
  • @SumitKumar your `c-style` string is not `null` terminated (`\0`) – KostasRim Sep 18 '16 at 10:48
  • writing to a memory which doesn't belong to an array doesn't throw an exception but prepare yourself for a real great disaster. – Raindrop7 Sep 18 '16 at 10:50
  • anything might happen, chaning the value of `a` is among the kindest things that can occur. You are lucky that your harddrive did not get erased :P – 463035818_is_not_an_ai Sep 18 '16 at 10:51
  • but shouldnt it just throw a seg fault error in such cases ? – Sumit Kumar Sep 18 '16 at 10:55
  • 1
    "Undefined behavior" means that anything can happen, and there is no defined result. It could be a segfault. It could be apparently correct results from the program. It could be a different result each time the program runs. – Sam Varshavchik Sep 18 '16 at 11:03
  • @SumitKumar tag me to answer providing you with a very useful example – Raindrop7 Sep 18 '16 at 11:08
  • 1
    @SumitKumar As soon as someone on this site (or elsewhere, of course) says your program invokes undefined behavior ("UB"), you can't reason about what "should" happen. That's kind of the point of the language giving you *undefined* behavior, there *is* no "should". – unwind Sep 18 '16 at 11:38
  • i was just checking the difference between an undefined behavior and a segmentation fault ..?! – Sumit Kumar Sep 18 '16 at 12:16

3 Answers3

1

//1. does not throw an error

In C and in C++ there is no bounds check because it is simply exposing raw memory.

That what is defined as Undefined Behaviour. That means (in very short) that the standard does not specify what will happen in your program, anything could happen when an instruction produces an undefined behaviour.

My suggest if you're using C++ (which is a different language from C) is to use std::vector class. Here References.

Note that std::vector produces an undefined behaviour when you try to access to a index out of bounds. With the method at, instead, an exception will throw in that case.

#include <vector>

int main(int argc, char* argv[]) {
  std::vector<char> a = {'a', 'b', 'c'};
  a.at(5);  // it will throw an exception
  return 0;
}

Moreover, if you have to manage strings the most convenient class is std::string.

BiagioF
  • 9,368
  • 2
  • 26
  • 50
  • but if there is no bounds checking done then how do we get segmentation faults..? – Sumit Kumar Sep 18 '16 at 10:57
  • @SumitKumar [Segfault](https://en.wikipedia.org/wiki/Segmentation_fault) happens when your program tries to access an invalid address memory. For example the memory space reserved to another program. In your case you probably still access in your program space and the operative system does not kill the process. – BiagioF Sep 18 '16 at 11:13
0

Accessing memory beyond the allocated chunk is an Undefined behavior.

for(i=0;i<5;i++)
{
    b[i]=a[i]; //1. does not throw an error
}

In this loop you will end up assigning b[3]=a[3] and b[4]=a[4];

b[3] and b[4] are unallocated chunks of memory. So accessing them is an undefined behavior.

There can be unpredictable results due to undefined behavior.

According to standard:

Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

Edit: For your doubt about segmentation fault:

Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you". But the reverse is not true i.e you can not say that you'll get a segmentation fault whenever you access an un-allocated memory.

There are systems out there that operate without memory protection, thus you cannot tell whether a piece of memory actually "belongs to you", and thus don't know whether segmentation fault will occur or not, only undefined behavior is assured.

Raman
  • 2,735
  • 1
  • 26
  • 46
  • then why in some cases we get a seg. fault error . How is seg fault different than this undefined behaviour ? – Sumit Kumar Sep 18 '16 at 11:01
  • @SumitKumar Whether to give seg. fault error or not is implementation defined. C standard doesn't have any such rules. You'll probably like to read this answer http://stackoverflow.com/a/25636788/4390699 – Raman Sep 18 '16 at 11:07
  • @SumitKumar I've edited my answer and tried to clear your doubt about segfault. – Raman Sep 18 '16 at 11:21
  • thanks..that clears it up a bit.. – Sumit Kumar Sep 18 '16 at 11:27
-1
char b[3]; // [X] [X] [NULL_CHAR] at this point

  int i=0;
  for(i=0;i<5;i++)
  {
     b[i]=a[i]; //1. does not throw an error
  }

so basically, your'e corrupting memory when i=3/4/5. this is undefined behaviour. if your program don't own that memory - it will be a seg. fault. but its only a matter of luck, this program behaviour is unexpected.

csStudent
  • 9
  • 2
  • exactly, i was expecting a seg fault error.. why does it not throw seg fault simply ?! – Sumit Kumar Sep 18 '16 at 10:54
  • 1
    This comment `// [X] [X] [X] [NULL_CHAR] at this point` is misleading or simply wrong. – alk Sep 18 '16 at 10:55
  • @SumitKumar It doesn't has to. There is no compulsory rule for issuance of a diagnostic message. – Raman Sep 18 '16 at 10:56
  • @SumitKumar: "*why does it not throw seg fault simply*" because Undefined Behaviour is .. well... undefined. – alk Sep 18 '16 at 10:56
  • `b[3]` is left uninitialised, so any of its elements may carry a null-character (`NUL`, `'\0'`, `0`) by accident only. – alk Sep 18 '16 at 11:02
  • @alk how do u differentiate seg faults and undefined behaviours ? – Sumit Kumar Sep 18 '16 at 11:02
  • seg fault notifying an operating system (OS) about a memory access violation, so if you by a "coincidence" do not accessing that memory, there's a chance that it won't throw a set fault, but u should not count on it. – csStudent Sep 18 '16 at 11:03
  • @SumitKumar: Invoking UB is the reason, the segmentation fault is *one* of its possible (final) outcomes. – alk Sep 18 '16 at 11:03