segfault strlen

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • danielesalatti@gmail.com

    #1

    segfault strlen

    Hello!!
    I'm studying c++ and I'm trying to get a little piece of code working,
    but I'm getting a segfault with strlen here:

    void tabhash::set (url *U) {
    uint hash = U->hashCode();
    char* url = U->giveUrl();
    char* chash = (char*)hash;

    char* Insert1="INSERT INTO sep_hashtable VALUES (";
    char* Insert2=",0,'";
    char* Insert3="');";

    char* Insert=new
    char[strlen(Insert1) +strlen(chash)+ strlen(Insert2) +strlen(url)+st rlen(Insert3)];
    strcpy( Insert, Insert1);
    strcat( Insert, chash);
    strcat( Insert, Insert2);
    strcat( Insert, url);
    strcat( Insert, Insert3);
    if (mysql_query(&m ysql,Insert)) {
    cerr << "Cannot insert into sep_hashtable : "
    << strerror(errno) << endl;
    exit(1);
    }
    }

    I can't find out why I'm getting this segfault error...can you help me
    a bit?

  • Jakob Bieling

    #2
    Re: segfault strlen

    danielesalatti@ gmail.com wrote:
    Hello!!
    I'm studying c++ and I'm trying to get a little piece of code working,
    but I'm getting a segfault with strlen here:
    >
    void tabhash::set (url *U) {
    uint hash = U->hashCode();
    char* url = U->giveUrl();
    char* chash = (char*)hash;
    Why are you casting an unsigned int to a char*? A cast is not a
    lexical conversion, which you have probably intended. But then I do not
    know how to interpret the return value of url::hashCode. But I doubt it
    is meant to be casted to a char*.

    hth
    --
    jb

    (reply address in rot13, unscramble first)


    Comment

    • SirMike

      #3
      Re: segfault strlen

      Dnia 28 Sep 2006 02:58:51 -0700, danielesalatti@ gmail.com napisa³(a):
      I'm studying c++ and I'm trying to get a little piece of code working,
      Are you sure it's c++? This code doesn't show it.
      Use i.e. std::string or std::stringstre am if you are about to write good
      c++ code.
      char* Insert1="INSERT INTO sep_hashtable VALUES (";
      char* Insert2=",0,'";
      char* Insert3="');";
      WTF? Don't do that. That's why you have segfault.
      If you still want to use C style strings try:

      char Insert1[] = {"abcd"};

      or allocate some memory before writing to the pointer:

      char *Insert1 = new char[BUFFER_SIZE];
      strcpy(Insert1, "abcd"); // BE CAREFUL - DO NOT PUT longer string than the
      buffer size

      --
      SirMike - http://www.sirmike.org

      C makes it easy to shoot yourself in the foot; C++ makes it harder, but
      when you do, it blows away your whole leg. - Bjarne Stroustrup

      Comment

      • Jacek Dziedzic

        #4
        Re: segfault strlen

        danielesalatti@ gmail.com wrote:
        Hello!!
        I'm studying c++ and I'm trying to get a little piece of code working,
        but I'm getting a segfault with strlen here:
        >
        void tabhash::set (url *U) {
        uint hash = U->hashCode();
        char* url = U->giveUrl();
        char* chash = (char*)hash;
        >
        char* Insert1="INSERT INTO sep_hashtable VALUES (";
        char* Insert2=",0,'";
        char* Insert3="');";
        >
        char* Insert=new
        char[strlen(Insert1) +strlen(chash)+ strlen(Insert2) +strlen(url)+st rlen(Insert3)];
        Shouldn't this buffer be bigger to allow for the terminating '\0'?
        strcpy( Insert, Insert1);
        strcat( Insert, chash);
        strcat( Insert, Insert2);
        strcat( Insert, url);
        strcat( Insert, Insert3);
        if (mysql_query(&m ysql,Insert)) {
        cerr << "Cannot insert into sep_hashtable : "
        << strerror(errno) << endl;
        exit(1);
        }
        }
        >
        I can't find out why I'm getting this segfault error...can you help me
        a bit?
        Anyway, that's what dealing with C-style strings usually brings
        about -- a lot of strcpy()'s, strcat()'s and buffer overruns.
        Consider using std::strings, they are way safer and can be
        concatenated like

        string Insert = Insert1 + Insert2 + Insert3;

        while automatically growing to accommodate their contents.

        HTH,
        - J.

        Comment

        • Jacek Dziedzic

          #5
          Re: segfault strlen

          SirMike wrote:
          Dnia 28 Sep 2006 02:58:51 -0700, danielesalatti@ gmail.com napisa³(a):

          >>I'm studying c++ and I'm trying to get a little piece of code working,

          Are you sure it's c++? This code doesn't show it.
          Use i.e. std::string or std::stringstre am if you are about to write good
          c++ code.
          This I agree with.

          >> char* Insert1="INSERT INTO sep_hashtable VALUES (";
          >> char* Insert2=",0,'";
          >> char* Insert3="');";

          WTF? Don't do that. That's why you have segfault.
          But not because of this? These are well formed
          C-style string literals. They are fine in themselves,
          except that they cannot be written to, right?
          If you still want to use C style strings try:

          char Insert1[] = {"abcd"};

          or allocate some memory before writing to the pointer:

          char *Insert1 = new char[BUFFER_SIZE];
          strcpy(Insert1, "abcd"); // BE CAREFUL - DO NOT PUT longer string than the
          buffer size
          ... or rather "longer string than buffer size minus one".

          - J.

          Comment

          • Eberhard Schefold

            #6
            Re: segfault strlen

            Jacek Dziedzic wrote:
            >> char* Insert1="INSERT INTO sep_hashtable VALUES (";
            >>
            >WTF? Don't do that. That's why you have segfault.
            >
            But not because of this? These are well formed
            C-style string literals. They are fine in themselves,
            except that they cannot be written to, right?
            They should be declared const, then the compiler will be able to help
            you. The standard still allows non-const for reasons of C compatibility,
            but this is deprecated.

            Comment

            • SirMike

              #7
              Re: segfault strlen

              Dnia Thu, 28 Sep 2006 13:57:14 +0200, Jacek Dziedzic napisa³(a):
              But not because of this? These are well formed
              C-style string literals. They are fine in themselves,
              except that they cannot be written to, right?
              You're right. I only tried to emphasize that the whole code was wrong ;)
              ... or rather "longer string than buffer size minus one".
              Exactly.

              --
              SirMike - http://www.sirmike.org

              C makes it easy to shoot yourself in the foot; C++ makes it harder, but
              when you do, it blows away your whole leg. - Bjarne Stroustrup

              Comment

              • Bart

                #8
                Re: segfault strlen

                danielesalatti@ gmail.com wrote:
                Hello!!
                I'm studying c++ and I'm trying to get a little piece of code working,
                but I'm getting a segfault with strlen here:
                Your first problem is that you're not really using C++. You're just
                using C++ as a better C. In C++ a much better way would be something
                like the following:

                #include <sstream>
                ....
                std::stringstre am stream;
                stream
                << "INSERT INTO seb_hashtable VALUES ("
                << hashcode
                << ",0,'"
                << url
                << "');"
                << std::flush;
                my_database.exe cute(stream.str ());

                See how easy? No need to manipulate char arrays and getting segfaults
                for weird reasons.

                You also have another potential problem too, but it's off-topic. Google
                "SQL injection" for more info.

                Regards,
                Bart.

                Comment

                • tragomaskhalos

                  #9
                  Re: segfault strlen


                  danielesalatti@ gmail.com wrote:
                  >
                  char* Insert=new
                  char[strlen(Insert1) +strlen(chash)+ strlen(Insert2) +strlen(url)+st rlen(Insert3)];
                  strcpy( Insert, Insert1);
                  strcat( Insert, chash);
                  strcat( Insert, Insert2);
                  strcat( Insert, url);
                  strcat( Insert, Insert3);
                  >
                  I can't find out why I'm getting this segfault error...can you help me
                  a bit?
                  You are only allocating enough memory in Insert for the characters
                  you're putting in there, you need to add one more for the null
                  terminator, ie:
                  char* Insert = new char[strlen(Insert1) +...+strlen(Ins ert3) /** NB**/ +
                  1];

                  But anyway, all those strcats are a very brain-damaged way of achieving
                  what you want. There are better ways of achieving this in C, but in C++
                  you should be using std::string and std::stringstre am. Look:

                  void tabhash::set (url *U) {
                  std::ostringstr eam os;
                  os << "INSERT INTO sep_hashtable VALUES ("
                  << U->hashCode()
                  << ",0,"
                  << U->giveUrl()
                  << ");"
                  ;
                  if (mysql_query(&m ysql, os.str().c_str( ))) {
                  cerr << "Cannot insert into sep_hashtable : "
                  << strerror(errno) << endl;
                  exit(1);
                  }
                  }

                  It's quite a bit cleaner, no ?

                  Comment

                  • Martin Steen

                    #10
                    Re: segfault strlen

                    danielesalatti@ gmail.com wrote:
                    char* Insert=new
                    char[strlen(Insert1) +strlen(chash)+ strlen(Insert2) +strlen(url)+st rlen(Insert3)];
                    Remember that in C and C++ a string is zero-terminated, so you must make
                    your stringbuffer large enough:

                    char* Insert = new char[LengthOffAllStr ings + 1];

                    That "+ 1" is important..

                    Best regards, Martin

                    Comment

                    • Ron Natalie

                      #11
                      Re: segfault strlen

                      Martin Steen wrote:
                      danielesalatti@ gmail.com wrote:
                      > char* Insert=new
                      >char[strlen(Insert1) +strlen(chash)+ strlen(Insert2) +strlen(url)+st rlen(Insert3)];
                      >>
                      >
                      Remember that in C and C++ a string is zero-terminated, so you must make
                      your stringbuffer large enough:
                      A C++ string is NOT necessarily null terminated.
                      It may contain nulls or not at any position.

                      It's only the use of char* as a defacto C-string that is so encumbered.

                      Comment

                      Working...