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?

4
  • 1
    char a[n] is invalid in C++. It's just an extension in some compilers Commented Nov 18, 2022 at 4:28
  • Why not use std::string::at for getting the n position character from a string? Commented Nov 18, 2022 at 4:32
  • Just curious to know the working of character arrays. Commented Nov 18, 2022 at 4:35
  • @VikashGola "Just curious to know the working of character arrays." -- One important factor here 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. Commented Nov 19, 2022 at 3:41

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

-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.)

2 Comments

"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 you're absolutely right. I have updated the answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.