C ++ class with char pointers returning garbage

I created an "Entry" class to handle dictionary entries, but in my main () I create Entry () and try to disable public char members, but I get garbage. When I look at the Watch list in the debugger, I see that the values ​​are being set, but as soon as I access the values, garbage appears. Can someone clarify what I can lose?

#include  <iostream>

using  namespace  std;

class Entry
{
    public:
            Entry(const char *line);
            char *Word;
            char *Definition;
};

Entry::Entry(const char *line)
{
    char tmp[100];
    strcpy(tmp, line);

    Word = strtok(tmp, ",") + '\0';
    Definition = strtok(0,",") + '\0';
}

int  main()
{
    Entry *e = new Entry("drink,What you need after a long day work");
    cout << "Word: " << e->Word << endl;
    cout << "Def: " << e->Definition << endl;
    cout << endl;

    delete e;
    e = 0;

    return  0;
}
+3
source share
4 answers

The word and definition both indicate tmp, which has gone out of scope and contains garbage.

+11
source

strtok() . , Entry:: Entry.

+4

tmp , , Word Definition. , , tmp . , char . , , C/++ . ASCII () , . , , , . strtok , - .

, :

#include  <iostream>

using  namespace  std;

class Entry
{
    public:
            Entry(const char *line);
            char *Word;
            char *Definition;

    private:
            char buffer[100];


};

Entry::Entry(const char *line)
{
    strncpy(buffer, line, sizeof buffer);
    buffer[sizeof buffer - 1] = '\0';

    Word = strtok(buffer, ",");
    Definition = strtok(0,",");
}

int  main()
{
    Entry *e = new Entry("drink,What you need after a long day work");
    cout << "Word: " << e->Word << endl;
    cout << "Def: " << e->Definition << endl;
    cout << endl;

    delete e;
    e = 0;

    return  0;
}

I changed the name from tmp to the buffer, since this is no longer a temporary value. I also used strncpy to prevent buffer overflows. Line buffer [sizeof buffer - 1] = '\ 0'; because if the string is larger than the buffer, there will be no terminator after the call.

+3
source

Actually, if this is due to the limitations of your appointment, I would recommend to give up char*, and strtok()in favor of string, istringstreamand getline():

#include <string>
#include <sstream>
#include <iostream>

using namespace std;

class Entry
{
  public:
    Entry(const string& line);
    string Word;
    string Definition;
};

Entry::Entry(const string& line)
{
  istringstream iss(line);
  getline(iss, Word, ',');
  getline(iss, Definition, ',');
}

int main()
{
  Entry e = Entry("drink,What comes between \"eat\" and \"be merry\"");
  cout << "Word: " << e.Word << endl;
  cout << "Def: " << e.Definition << endl;
  cout << endl;

  return  0;
}
+1
source

Source: https://habr.com/ru/post/1736015/


All Articles