4

I have some trouble using strcpy with a vector of instances of my own class. Here's the class:

class elemente {  
    char name[5];  
    short val;  
    bool red;  
};

So, I made a vector from this class:

vector<elemente> ele(1);  

But if I try to do this operation:

strcpy(ele.back().name, strtok(line, " "));  

I always get Segmentation Fault. Why?

I used GDB to debug my program, and the line variable is correct, and also if I replace the vector with a normal char * everything works fine (The programs doesn't work, but the content is all right).

What can I do?

LihO
  • 41,190
  • 11
  • 99
  • 167
StefanEuSunt
  • 133
  • 1
  • 6
  • 1
    Because the result of `strtok` has more than 4 characters? – Oliver Charlesworth Feb 23 '13 at 11:10
  • 6
    You're programming in C++, not C. So get rid of that `strcpy` and `strtok` functions and change the type of `elemente::name` to `std::string` – LihO Feb 23 '13 at 11:11
  • Impossible, I checked it with another variable, the result is 2 chars long – StefanEuSunt Feb 23 '13 at 11:11
  • 3
    **if I replace the vector with a normal char * everything works fine** That probably just made matters worse, you just didn't realize it :) – jrok Feb 23 '13 at 11:12
  • @user2098833: In that case, please post a [test-case](http://sscce.org)! – Oliver Charlesworth Feb 23 '13 at 11:15
  • 3
    This is not a good question. It dangles a tantalizingly small segment of code that possibly has a multitude of problems and we're expected to guess exactly which one occurs here. Ideally your question should include a complete, but still *minimal* example that illustrates your problem. Everything from `int main()` upwards I need to compile and reproduce your problem on my machine. – Flexo Feb 23 '13 at 11:30
  • 1
    my telepathic skills tell me that whatever the line variable is, it isn't writable. strtok mangles the input string while tokenizing – Anya Shenanigans Feb 23 '13 at 11:31
  • I agree with @Petesh: chances are that `line` is `"abcd"` or some such, not a modifiable string. In which case, the problem has nothing to do with `vector` or `strcpy`; it's `strtok` that's writing where writing isn't allowed. – Pete Becker Feb 23 '13 at 13:03

1 Answers1

3

Since you are using C++, you should use features this language provides you instead of struggling with C-style code. It's good that you decided to use std::vector so continue and use std::string for storing strings, std::istringstream for creating an input stream that you will read the tokens from and std::getline to actually retrieve these tokens.

At first, use an access specifier public to make the attributes of the elemente class available outside the scope of this class and change the type of name to std::string:

class elemente
{
public:
    std::string name;
    // ...
};

Then retrieving tokens from the line could look like this:

#include <iostream>
#include <vector>
#include <sstream>
...

std::vector<elemente> elements;
std::string line("this is my input line");

std::istringstream lineStream(line);
for (std::string word; std::getline(lineStream, word, ' '); )
{
    if (!word.empty())
    {
        elements.push_back(elemente());
        elements.back().name = word;
    }
}

And to test this code, you can just print all names stored within elements of this vector:

std::vector<elemente>::iterator e;
for(e = elements.begin(); e != elements.end(); ++e)
    std::cout << e->name << ".";

outputs:

this.is.my.input.line.

Alternatively you could create a public constructor of your class so that you can construct your elements with properly initialized members:

class elemente
{
public:
    elemente(const std::string& s) : name(s){ }
// ...
    std::string name;
    // ...
};

Then parsing of tokens would become:

for (std::string word; std::getline(lineStream, word, ' '); )
{
    if (!word.empty())
        elements.push_back(elemente(word));
}

Hope this helps :)

LihO
  • 41,190
  • 11
  • 99
  • 167