views:

187

answers:

4

Hello,

I created a struct to hold some data and then declared a vector to hold that struct.

But when I do a push_back I get damn segfault and I have no idea why!

My struct is defines as:

typedef struct Group
{
    int codigo;
    string name;
    int deleted;
    int printers;
    int subpage;

    /*included this when it started segfaulting*/
    Group(){ name.reserve(MAX_PRODUCT_LONG_NAME); }
    ~Group(){ name.clear(); }
    Group(const Group &b)
    {
    codigo = b.codigo;
    name = b.name;
    deleted = b.deleted;
    printers = b.printers;
    subpage = b.subpage;
    }
   /*end of new stuff*/
 };

Originally, the struct didn't have the copy, constructor or destructor. I added them latter when I read this post below.

http://stackoverflow.com/questions/676575/seg-fault-after-is-item-pushed-onto-stl-container

but the end result is the same.

There is one this that is bothering me as hell! When I first push some data into the vector, everything goes fine. Later on in the code when I try to push some more data into the vector, my app just segfaults!

The vector is declared

vector<Group> Groups

and is a global variable to the file where I am using it. No externs anywhere else, etc...

I can trace the error to:

_M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage- this->_M_impl._M_start);

in vector.tcc when I finish adding/copying the last element to the vector....

As far as I can tell. I shouldn't be needing anything to do with a copy constructor as a shallow copy should be enough for this. I'm not even allocating any space (but I did a reserve for the string to try out).

I have no idea what the problem is!

I'm running this code on OpenSuse 10.2 with gcc 4.1.2

I'm not really to eager to upgrade gcc because of backward compatibility issues...

This code worked "perfectly" on my windows machine. I compiled it with gcc 3.4.5 mingw without any problems...

help!

--- ... ---

:::EDIT:::

I push data

Group tmp_grp;

(...)

tmp_grp.name = "Nova ";
tmp_grp.codigo=GetGroupnextcode();
tmp_grp.deleted=0;
tmp_grp.printers=0;
tmp_grp.subpage=0;
Groups.push_back(tmp_grp);
+1  A: 

You should definitely remove the destructor. C++ will automatically call the destructor of all data members, and doing things to members that already have a destructor like that is unnecessary and could be unsafe.

But, I don't see anything wrong with your code per-se. You will have to post a little more of it. Try expanding the (...) section - show us all the code that involves the vector.

DeadMG
+6  A: 

Like Neil said, you don't need a default constructor, copy constructor, or destructor:

  • std::string cleans up after itself, so your destructor is never necessary.
  • The compiler-provided shallow copy constructor will work just fine.
  • std::string::reserve is unnecessary, since std::string will dynamically allocate memory as needed, but it may provide a performance benefit.

The code that you posted looks correct (and it looks very simple and straightforward, so it's hard to see where an error could creep in). Therefore, I suspect that you're corrupting memory elsewhere in your code and that the vector<Group> is simply the victim.

Try installing Valgrind (OpenSuse should provide a package for it) and run your application through it (from the command line, just run valgrind my-app) to see if Valgrind can catch any memory corruption.

Josh Kelley
+1  A: 

Memory errors like this can be caused by deleting the same memory twice or deleting memory you didn't get from new. The errors often occur long after the fact in places like this. As DeadMG already stated install valgrind and look for other seemingly unrelated memory problems.

John Gordon
A: 

Well...

valgrind to the rescue! What called out to me in the valgrind log was this piece.

Invalid write of size 4
==4639==    at 0x805BDC0: ChangeGroups() (articles.cpp:405)
==4639==    by 0x80AC008: GeneralConfigChange() (config.cpp:4474)
==4639==    by 0x80EE28C: teste() (main.cpp:2259)
==4639==    by 0x80EEBB3: main (main.cpp:2516)

At this point in the file I was doing this

Groups[oldselected].subpage=SL.selected_code();

and what if oldselected was outside the bounds of the vector?

In this case what was happening was that oldselected could be -1... and although this wasn't crashing at this point, it was writing something somewhere else...

I should probably start using the at() operator and check for the exception or just check if "oldselected" is >0 and < Groups.size() [preferred solution].

So kudos to John and Josh for reminding me of valgrind.

I've used it before, but never needed to do anything t significant with it (fortunately :D).

It's interesting that in windows I don't get this segfault. The problem was the same... I guess that it has something to do with memory management and the compiler... it really eludes me.

Thanks everyone for the input ;)

Cheers

Andre