std::string and gcc problem ?

Discussion in 'C++' started by daroman@gmx.net, Mar 7, 2007.

  1. Guest

    Hi Guys,
    i've problem with my small C++ programm. I've just small template
    class which represetns a array, everything works fine up to
    combination with std::string. I did tried it with M$ VC++ and with GCC
    (Cygwin and Linux) and my problem is when i try do this

    int main(int argc, char **argv) {
    array<std::string> a(10);

    a[0] = "Huhuhu"; <--- with gcc i got a crash !

    std::string = a[0];
    return 0;
    }


    the program crashes with segmentation fault on std::string::assign(),
    but just with gcc ?!
    Can somebode help me solve this problem ?

    peter

    .... and here is my code

    #ifndef _array_h
    #define _array_h
    #include <stdexcept>
    #include <sstream>
    #include <stdlib.h>
    #include <memory.h>
    #ifdef _DEBUG
    #include <iostream>
    #endif

    template <typename T>
    class array {
    public:
    array(size_t ) throw(std::bad_alloc &);
    array(const array<T> & ) throw(std::bad_alloc &);
    ~array();

    T& operator[](size_t ) throw(std::eek:ut_of_range &);
    const T&operator[](size_t ) const throw(std::eek:ut_of_range &);

    size_t length() const { return size; }

    int compare(const array<T> & ) const;

    bool operator==(const array<T> &arg ) { return compare(arg) == 0; }
    bool operator!=(const array<T> &arg ) { return compare(arg) != 0; }
    bool operator<(const array<T> &arg ) { return comapre(arg) < 0; }
    bool operator>(const array<T> &arg ) { return compare(arg) > 0; }
    bool operator!() const { return length > 0; }

    private:
    T *data;
    size_t size;
    };

    #endif

    template <typename T>
    array<T>::array(size_t e) throw(std::bad_alloc & )
    {
    data = NULL; size = 0;
    data = new T[e];
    size = e;
    }

    template <typename T>
    array<T>::~array()
    {
    if(data != NULL)
    delete [] data;
    data = NULL;
    size = 0;
    }

    template <typename T>
    const T& array<T>::eek:perator[](size_t idx) const
    throw(std::eek:ut_of_range &)
    {
    if(idx > size) {
    std::stringstream error;
    error << "idx > size " << __FILE__ << "(" << __FUNCTION__ << ":" <<
    __LINE__ << ")";
    #ifdef _DEBUG
    std::cerr << error.c_str() << std::endl;
    #endif
    throw std::eek:ut_of_range(error.str());
    }

    return data[idx];
    }


    template <typename T>
    T& array<T>::eek:perator[](size_t idx) throw(std::eek:ut_of_range &)
    {
    if(idx > size) {
    std::stringstream error;
    error << "idx > size " << __FILE__ << "(" << __FUNCTION__ << ":" <<
    __LINE__ << ")";
    #ifdef _DEBUG
    std::cerr << error.str().c_str() << std::endl;
    #endif
    throw std::eek:ut_of_range(error.str());
    }

    return data[idx];
    }
     
    , Mar 7, 2007
    #1
    1. Advertising

  2. wrote:
    > i've problem with my small C++ programm. I've just small template
    > class which represetns a array, everything works fine up to
    > combination with std::string. I did tried it with M$ VC++ and with GCC
    > (Cygwin and Linux) and my problem is when i try do this
    >
    > int main(int argc, char **argv) {


    Why do you need 'argc' and 'argv'? You never use them!

    > array<std::string> a(10);


    'array' is undeclared at this point. But presuming you have included
    your template definition from below somehow... Supposedly here you
    have create an array that internally allocates 10 strings and allows
    you the use of all of them, right?

    >
    > a[0] = "Huhuhu"; <--- with gcc i got a crash !


    And with VC++ you don't, correct?

    So, 'a[0]' returns a reference to the zeroth element in your array in
    the 'a' object. Having looked at the operator[], I don't see any
    problem with it. Did you try using a debugger to see what values you
    get into the 'std::string::assign'?

    >
    > std::string = a[0];


    This shouldn't even compile! How did you get a crash? Are you
    sure you posted your _real_ code?

    > return 0;
    > }
    >
    >
    > the program crashes with segmentation fault on std::string::assign(),
    > but just with gcc ?!
    > Can somebode help me solve this problem ?


    If it's a GNU-specific problem, GNU people should be able to help.
    The code looks fine but only if one assumes that the stuff that you
    omitted is correct.

    >
    > peter
    >
    > ... and here is my code
    >
    > #ifndef _array_h
    > #define _array_h


    Avoid leading underscores like the plague. Any identifier that begins
    with an underscore is reserved in the global namespace.

    > #include <stdexcept>


    No such standard header.

    > #include <sstream>
    > #include <stdlib.h>
    > #include <memory.h>
    > #ifdef _DEBUG
    > #include <iostream>
    > #endif
    >
    > template <typename T>
    > class array {
    > public:
    > array(size_t ) throw(std::bad_alloc &);
    > array(const array<T> & ) throw(std::bad_alloc &);
    > ~array();
    >
    > T& operator[](size_t ) throw(std::eek:ut_of_range &);
    > const T&operator[](size_t ) const throw(std::eek:ut_of_range &);
    >
    > size_t length() const { return size; }
    >
    > int compare(const array<T> & ) const;
    >
    > bool operator==(const array<T> &arg ) { return compare(arg) == 0; }
    > bool operator!=(const array<T> &arg ) { return compare(arg) != 0; }
    > bool operator<(const array<T> &arg ) { return comapre(arg) < 0; }
    > bool operator>(const array<T> &arg ) { return compare(arg) > 0; }


    Why aren't those operators 'const'?

    > bool operator!() const { return length > 0; }
    >
    > private:
    > T *data;
    > size_t size;
    > };
    >
    > #endif
    >
    > template <typename T>
    > array<T>::array(size_t e) throw(std::bad_alloc & )
    > {
    > data = NULL; size = 0;


    What is that for?

    > data = new T[e];
    > size = e;
    > }
    >
    > template <typename T>
    > array<T>::~array()
    > {
    > if(data != NULL)
    > delete [] data;
    > data = NULL;
    > size = 0;
    > }
    >
    > template <typename T>
    > const T& array<T>::eek:perator[](size_t idx) const
    > throw(std::eek:ut_of_range &)
    > {
    > if(idx > size) {
    > std::stringstream error;
    > error << "idx > size " << __FILE__ << "(" << __FUNCTION__ << ":" <<
    > __LINE__ << ")";
    > #ifdef _DEBUG
    > std::cerr << error.c_str() << std::endl;
    > #endif
    > throw std::eek:ut_of_range(error.str());
    > }
    >
    > return data[idx];
    > }
    >
    >
    > template <typename T>
    > T& array<T>::eek:perator[](size_t idx) throw(std::eek:ut_of_range &)
    > {
    > if(idx > size) {
    > std::stringstream error;
    > error << "idx > size " << __FILE__ << "(" << __FUNCTION__ << ":" <<
    > __LINE__ << ")";
    > #ifdef _DEBUG
    > std::cerr << error.str().c_str() << std::endl;
    > #endif
    > throw std::eek:ut_of_range(error.str());
    > }
    >
    > return data[idx];
    > }


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 7, 2007
    #2
    1. Advertising

  3. Gavin Deane Guest

    On 7 Mar, 13:59, "Victor Bazarov" <> wrote:
    > wrote:
    > > #include <stdexcept>

    >
    > No such standard header.


    Where does your implementation declare std::logic_error and the like
    then?

    Gavin Deane
     
    Gavin Deane, Mar 7, 2007
    #3
  4. Gavin Deane wrote:
    > On 7 Mar, 13:59, "Victor Bazarov" <> wrote:
    >> wrote:
    >>> #include <stdexcept>

    >>
    >> No such standard header.

    >
    > Where does your implementation declare std::logic_error and the like
    > then?


    My mistake.
     
    Victor Bazarov, Mar 7, 2007
    #4
  5. Grizlyk Guest

    wrote:
    >
    > int main(int argc, char **argv)

    argc, argv are never used

    > {
    > array<std::string> a(10);
    >
    > a[0] = "Huhuhu"; <--- with gcc i got a crash !

    comment sign // lost

    >
    > std::string = a[0];

    error assignment to type

    std::string tmp= a[0];

    > return 0;
    > }
    >
    > template <typename T>
    > class array {
    > public:
    > array(size_t ) throw(std::bad_alloc &);
    > array(const array<T> & ) throw(std::bad_alloc &);


    extra <T> for "array<T> &"
    array(const array& ) throw(std::bad_alloc &);

    assignment operator lost
    array& operator=(const array& ) throw(std::bad_alloc &);

    >
    > template <typename T>
    > array<T>::array(size_t e) throw(std::bad_alloc & )
    > {
    > data = NULL; size = 0;
    > data = new T[e];
    > size = e;
    > }

    assignment instead of initialization,
    extra assignment to data, size

    template <typename T>
    array<T>::array(size_t e) throw(std::bad_alloc & )
    :data( e? new T[e]: 0),
    size(e)
    {}

    >
    > template <typename T>
    > array<T>::~array()
    > {
    > if(data != NULL)

    rare needed, here extra comparsion with "data"

    > delete [] data;
    > data = NULL;

    rare needed, here extra assignment to "data"

    > size = 0;

    more rare needed, here extra assignment to "size"

    > }
    >
    > template <typename T>
    > const T& array<T>::eek:perator[](size_t idx) const
    > throw(std::eek:ut_of_range &)
    > {
    > if(idx > size) {


    if(idx >= size) {

    assuming idx, size unsigned
    size is 1..N or empty
    idx is 0..size-1 or overflow

    > std::stringstream error;
    > error << "idx > size " << __FILE__ << "(" << __FUNCTION__ << ":" <<
    > __LINE__ << ")";
    > #ifdef _DEBUG
    > std::cerr << error.c_str() << std::endl;
    > #endif
    > throw std::eek:ut_of_range(error.str());
    > }
    >
    > return data[idx];
    > }
    >
    >
    > template <typename T>
    > T& array<T>::eek:perator[](size_t idx) throw(std::eek:ut_of_range &)
    > {
    > if(idx > size) {


    if(idx >= size) {

    > std::stringstream error;
    > error << "idx > size " << __FILE__ << "(" << __FUNCTION__ << ":" <<
    > __LINE__ << ")";
    > #ifdef _DEBUG
    > std::cerr << error.str().c_str() << std::endl;
    > #endif
    > throw std::eek:ut_of_range(error.str());
    > }
    >
    > return data[idx];
    > }


    ***********

    > a[0] = "Huhuhu"; //<--- with gcc i got a crash !


    std::string::assign(...
    /**
    * The data is copied,

    so must not be errors here

    --
    Maksim A. Polyanin
    http://grizlyk1.narod.ru/cpp_new

    "In thi world of fairy tales rolls are liked olso"
    /Gnume/
     
    Grizlyk, Mar 8, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page