Menu

array question

Osito
2007-08-19
2012-09-26
  • Osito

    Osito - 2007-08-19

    I thought I was finally beginning to get the hang of arrays and pointers but I guess not. I'm having trouble defining an array of strings and manipulating it.

    It doesn't like this:

    static unsigned char g_temp[][] = {"ABC","DEF","GHI"};

    But this is OK:

    static unsigned char *g_temp[] = {"ABC","DEF","GHI"};

    However if I try to copy into that array from another similarly defined array it crashes:

    static unsigned char g_temp[] = {"ABC","DEF","GHI"};
    static unsigned char
    g_temp2[] = {"ABC","DEF","GHI"};
    strcpy(g_temp[0],g_temp2[0]);

    But if I define the size of the arrays explicitly it works and copy also works without crashing.

    static unsigned char g_temp[3][3] = {"ABC","DEF","GHI"};
    static unsigned char g_temp2[3][3] = {"ABC","DEF","GHI"};
    strcpy(g_temp[0],g_temp2[0]);

    Can someone explain why these things work and don't work, and also show me what is the best way to define an array of different-length strings that can be manipulated with strcpy.

     
    • Anonymous

      Anonymous - 2007-08-19

      >> ...it's really for modbus serial data, which is unsigned.
      It should not matter, signedness is a matter of interpretation not representation, the bit pattern is identical. It may be better to use a cast at the point you pass it to the modbus interface.

      >> ...I was surprised it didn't complain when I passed an unsigned to strcpy...
      It will generate a warning with the appropriate compiler options. I recommend at least -Wall -Werror -Wformat. In C++ it is an error to have a signed/unsigned mismatch for pointers without a cast. Note also that the 'signedness' of plain char is implementation (and often compiler option) dependent, and that it may work on one compiler because char is unsigned, and not on another because it is signed.

      Clifford

       
      • Osito

        Osito - 2007-08-24

        I finally got around to trying out your -Wall -Werror -Wformat suggestion. Is that mentioned in the FAQ? It probably should be. I figured when I saw the compiler option "Inhibit All Warning Messages" and it was set to "No", that I would get all the warning messages. But that's not the case.

        On the issue of signed vs. unsigned, what happens when you set a signed char to 0xff, as in i=0xff? Do you need to cast? If I convert all my unsigned char to signed char, am I going to have to go back and find all the places where I assume I'm calculating an unsigned 0 to 255 and cast that?

         
    • Anonymous

      Anonymous - 2007-08-19

      >> It doesn't like this:
      That is because it is only teh last subscript that can be left empty, it is determined by the number of initialisers.

      >> But this is OK:
      No it is not it is a dangerous misconception. It defines an array of pointers to constant data. It should really be declared thus:

      static const char g_temp[][] = {"ABC","DEF","GHI"};

      Note: Never qualify strings with "unsigned" or "signed" - do that only when using char as a small integer. The C string library takes parameters of type "char", specifying a signedness leads to type mismatches and portability issues.

      >> However if I try to copy into that array from another similarly defined array it crashes
      Of course it does it is constant data!

      >>But if I define the size of the arrays explicitly it works and copy
      Of course, because now you have created an array of string variables.

      >> ...best way to define an array of different-length strings...
      C/C++ does not support "jagged arrays", all elements have to be the same size. One solution is to make all elements 'worst-case' size, but this is not very flexible. An alternative is to create an array of pointers, and then malloc() each pointer to the appropriate size. A far far simpler method is to use an array of C++ <string> objects.

      Clifford

       
      • Osito

        Osito - 2007-08-19

        Thanks for the info. I'm using unsigned on purpose because it's really for modbus serial data, which is unsigned. I was just using the letters ABC etc. as an example. I know the string library takes char, and I was surprised it didn't complain when I passed an unsigned to strcpy during my debug efforts.

        I think I'll stick with making all elements worst-case size for now since it works and it's not too much wasted memory in this case.

         

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.