0

I run this test:

TEST_F(CHAR_TESTS, wtf){
  char letter[3] = {'A','B','C'};
  char types[2] = {'o','s'};
  char tmp[3];
  for(int i=0;i<3;i++){
    for(int j=0;j<3;j++){
      for(int k=0;k<2;k++){
        tmp[0]=letter[i];
        tmp[1]=letter[j];
        tmp[2]=types[k];
        std::string combination(tmp);
        std::cout << combination << std::endl;
      }
    }
  }
}

For some reason, this print this:

AAo~
AAs~
ABo~
ABs~
ACo~
ACs~
BAo~
BAs~
BBo~
BBs~
BCo~
BCs~
CAo~
CAs~
CBo~
CBs~
CCo~
CCs~

I do not think it is an issue with the printing itself, as I ended up doing this after noticing some tests comparing strings generated from char arrays were not passing, and I could not figure out why. So it feels like indeed the "combination" strings do not end up having the expected content.

The same code in a "regular" executable (not a gtest) print out what is expected (the 3 chars without the weird supplementary chars).

Vince
  • 3,979
  • 10
  • 41
  • 69

3 Answers3

5

Unfortunately std::string does not have a constructor that takes a reference to array of char. So you end up invoking the const char* constructor, and this one requires the pointer to point to the first element of a null terminated string. Your char arrays aren't null-terminated, so you end up with undefined behaviour.

You should null-terminate tmp, which you can do by declaring it with one extra character, and setting it to '\0'. You can achieve that like this

char tmp[4] = {};
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Or `char tmp[4] = "";` – Keith Thompson Oct 06 '17 at 23:39
  • damn, I just read this a little too fast: https://stackoverflow.com/questions/8960087/how-to-convert-a-char-array-to-a-string : "the string class has a constructor that takes a NULL-terminated C-string", I skipped the "NULL-terminated part". – Vince Oct 07 '17 at 09:38
  • 1
    You could also use `std::string combination(std::begin(tmp), std::end(tmp));` – legalize Oct 09 '17 at 18:58
1

The constructor in std::string combination(tmp); only works if tmp is nul terminated. Otherwise the constructor cannot find the length of the string.

However, you can help std::string by explicitly providing the size of the buffer:

std::string combination(tmp, sizeof(tmp));

This constructor is primarilly intended to construct a std::string from a part of a C-style string, but also works if given the full length.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
0

char tmp[3]; is not null-terminated use char tmp[4] = {0};