-6

Could someone explain to me, why there are 4 additional slots in char tab[], when I asked only for 3? How to get rid of them? I'm coding in Visual Studio 2017. Edit: the first program was very basic and didn't show what I intended. So, there is an extended one.

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int i, n;
    vector<char> input;
    char chp;
    cout << "Enter a expression" << endl;
    while (1)
    {
        cin.get(chp);
        if (chp == '\n') break;
        input.push_back(chp);
    }
    n = input.size();
    char* tab = new char[n] {};
    for (i = 0; i < n; i++)
    {
        tab[i] = input[i];
    }
    int l = strlen(tab);
    for (int i = 0; i < l; i++) 
    {
        cout << "tab[" << i << "] is " << tab[i] << endl;
    }
    cin.get();
}

Result in console window is similar, when I enter "3+3"

tab[0] is 3
tab[1] is +
tab[2] is 3
tab[3] is ř
tab[4] is ř
tab[5] is ř
tab[6] is ř

This isn't still the full program (full program is a calculator, that calculates any math expression, and is much longer). I wrote that in C long time ago, and in C dynamic arrays are not such a problem.

Also, what about multidimensional arrays? Can string be a solution also for them?

  • 6
    `tab` points to an array of uninitialized `char`. `strlen`does not return the size of the array, it depends on it's content. – François Andrieux Jan 22 '19 at 18:37
  • 5
    https://en.cppreference.com/w/cpp/string/byte/strlen: _The behavior is undefined if there is no null character in the character array pointed to by str._ – Daniel Langr Jan 22 '19 at 18:37
  • Change `char* tab = new char[3];` to `char* tab = new char[3]{};` Although do you want to allocate a dynamic array capable of storing 2 only characters (and the null terminator)? Maybe you want a `std::string` which is the proper way to use strings in `c++` – drescherjm Jan 22 '19 at 18:39
  • Possible duplicate of [Accessing an array out of bounds gives no error, why?](https://stackoverflow.com/questions/1239938/accessing-an-array-out-of-bounds-gives-no-error-why) – Algirdas Preidžius Jan 22 '19 at 18:39
  • 1
    when you use `std::string` and `std::vector` it is much harder to make mistakes of that kind – 463035818_is_not_an_ai Jan 22 '19 at 18:47
  • 1
    Just use `std:string` and be happy. – πάντα ῥεῖ Jan 22 '19 at 18:48
  • strlen was only there to demonstrate what is stored in memory. Initializing as empty {} helped. I don't wat to allocate a dynamic array capable of storing only 3 characters, this was just an example :) – Piotr Gruchalski Jan 22 '19 at 18:49
  • 3
    @PiotrGruchalski As a rule of thumb: Do not try to manage memory allocation yourself in c++ unless you're 100% sure you have to. Just use standard library containers and smart pointers. It's unlikely you can do that better yourself. – πάντα ῥεῖ Jan 22 '19 at 18:55
  • 1
    Your revised code still has the same problem, `tab` is not null terminated. You need to allocate `n+1` characters to hold a C-style string of length `n`. – Blastfurnace Jan 22 '19 at 19:16

1 Answers1

6

Could someone explain to me, why there are 4 additional slots in char tab[], when I asked only for 3?

There aren't. The array has only 3 elements.

The problem is that your array elements have indeterminate values. As a consequence of passing a pointer to array of indeterminate values into strlen, the behaviour of your program is undefined.

Solution: Initialise your array. Furthermore, initialise it so that it contains a null terminator, as required by strlen:

char* tab = new char[3]{'a', 'b', '\0'};

As alternative to null termination, don't use strlen to get the length. You already know that the array contains 3 elements. But the values must still be initialised before you insert them into the output stream.

P.S. Don't forget to delete memory that you allocate:

delete[] tab;
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • If the array has a size of 3, the longest null terminated string it should contain is 2. So using `3` isn't quite a replacement for `strlen`. Edit : Though I agree it seems the original intention was to inspect every byte of the array, so while this would have a different behavior then the original code it's likely what OP wants to do. – François Andrieux Jan 22 '19 at 18:47
  • The problem is, I don't know how many elements there will be. 3 is only for example. So initialization does't help. – Piotr Gruchalski Jan 22 '19 at 18:55
  • @PiotrGruchalski If you don't know then use `std::string` as other suggested. On the contrary to dynamically allocated character arrays, the capacity of `std::string` objects can grow. – Daniel Langr Jan 22 '19 at 19:01
  • @PiotrGruchalski not knowing the number of elements before hand does not prevent initialisation. – eerorika Jan 22 '19 at 19:34