0

Program :

#include <iostream>
using namespace std;

int main()
{
    int n;  // n=3
    cin >> n;
    char a[n];
    cin >> a;
    cout << a;
    return 0;
}

input :

3
Hello

output :

Hello

Why is my output "Hello" instead of "Hel"?

Also, if directly assign like char a[3] then I get a error of "stack smashing detected".

Can somebody explain what's going on here?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    `char a[n]` is invalid in C++. It's just an extension in some compilers – phuclv Nov 18 '22 at 04:28
  • Why not use [std::string::at](https://cplusplus.com/reference/string/string/at/) for getting the n position character from a string? – Joel Nov 18 '22 at 04:32
  • Just curious to know the working of character arrays. – Vikash Gola Nov 18 '22 at 04:35
  • @VikashGola *"Just curious to know the working of character arrays."* -- One important factor here is [array to pointer decay](https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay), which results in the operators `<<` and `>>` not knowing the size of your array. Once you internalize that tidbit, your results should be less surprising. – JaMiT Nov 19 '22 at 03:41

2 Answers2

1
cin >> n;
char a[n];

Variable-length arrays are not standard C++. Fixed-length arrays must have their sizes known at compile-time. For arrays whose sizes are not known until runtime, you must use new[] or better std::vector instead.

Why aren't variable-length arrays part of the C++ standard?

cin >> a;

This exhibits undefined behavior. You have allocated space for the array to hold only 3 chars, but your input has 5 chars, plus a null terminator. operator>> has no idea how much memory you have allocated, it simply reads input until a whitespace char is encountered. So, you are reading 5 chars and a null terminator into the array, overflowing the array and writing into surrounding memory. And since the array is allocated on the stack, you may end up with a runtime error about stack corruption (if you have configured your compiler to enable that option).

To do what you are attempting, you would need to allocate +1 more char to account for the null-terminator, and then use cin.get() instead of operator>> so you can specify the max size of the array being written into, eg:

char *a = new char[n+1];
cin.get(a, n+1);
...
delete[] a;

Or

std::vector<char> a(n+1);
cin.get(a.data(), n+1);
...
cout << a;

This just prints from memory until a null terminator is reached. It has no concept what the allocated size of the array is, or that you are asking it to print from corrupted memory. That is why you see the full input being printed.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
-1

According to the documentation,

NOTE: The elements field within square brackets [], representing the number of elements in the array, must be a constant expression, since arrays are blocks of static memory whose size must be determined at compile time, before the program runs.

When complied, all the initializatiosn and allocations happen even before your IO statements. And thus in actual comiling phase your code is nothing but like the below program:

int n;  // n=3
char a[n];

cin >> n;
cin >> a;
cout << a;

Thus, for some other compilers (or even with the same compiler in other systems) you may get segmantation fault as well.

Update: JaMiT's comment -

If a compiler does not support variable length arrays, then the length of the array is determined at compile time. This occurs before n is given a memory location with some random value. The value of n is not known at compile time, so compilation will fail if variable length arrays are not supported. (If VLAs are supported, then n will be given a value before the array is allocated.)

Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
  • *"At that point whatever the random value of n is used to decide the length of the array a."* -- this is false. If a compiler does not support variable length arrays, then the length of the array is determined **at compile time**. This occurs **before** `n` is given a memory location with some random value. The value of `n` is not known at compile time, so *compilation will fail* if variable length arrays are not supported. (If VLAs are supported, then `n` will be given a value before the array is allocated.) – JaMiT Nov 18 '22 at 05:38
  • @JaMiT you're absolutely right. I have updated the answer. – Sazzad Hissain Khan Nov 18 '22 at 06:07