unable to read char * strings from a buffer

Discussion in 'C++' started by nass, Nov 14, 2006.

  1. nass

    nass Guest

    hello everyone, i have a bit of problem reading char * strings from a
    buffer (a shared memory, pointed to by 'file_memory').
    basically i have a structure in memory 'ShMem' that can be accessed by
    2 applications (or will be at least when it is done).
    the structure is declared in the procedure under the pointer infoVar.
    members tXXL are integer lengths of the strings that as all saved
    (concatenated) at address of oAndS_str, which is of type char.
    i do not get the right values back however, and i wonder if the tXX
    'reconstruction strings' are assigned values properly with memcpy.

    void readingTheShMem()
    {
    int tOTL=0;
    int tONL=0;
    int tSNL=0;
    int tSLL=0;
    int tIDL=0;
    int tMDL=0;
    int readingLength;

    //lock the file for writing
    memset (&lock, 0, sizeof(lock));
    lock.l_type = F_WRLCK;
    fcntl (fd, F_SETLKW, &lock);

    struct ShMem *infoVar=(ShMem*)((char*)file_memory);

    tOTL = infoVar->oTL;
    tONL = infoVar->oNL;
    tSNL = infoVar->sNL;
    tSLL = infoVar->sLL;
    tIDL = infoVar->iDL;
    tMDL = infoVar->mDL;
    readingLength = tOTL + tONL + tSNL + tSLL + tIDL + tMDL ;
    char *readingStrs[readingLength];
    printf("reading length = %d\n", readingLength);
    printf("the infoVar->oAndS_str reading points
    to=%p\n",&(infoVar->oAndS_str));
    memcpy(readingStrs, &(infoVar->oAndS_str),
    readingLength);

    //unlock the file to allow access
    lock.l_type = F_UNLCK;
    fcntl (fd, F_SETLKW, &lock);

    char *tOT[tOTL]; memcpy(tOT,readingStrs,tOTL);
    printf("tOTL = %d and oT ptr = %p\n", tOTL, readingStrs);
    char *tON[tONL]; memcpy(tON,(readingStrs+tOTL),tONL);
    printf("tONL = %d and oN ptr = %p\n", tONL,
    (readingStrs+tOTL));
    char *tSN[tSNL];
    memcpy(tSN,(readingStrs+tOTL+tONL),tSNL);
    printf("tSNL = %d and sN ptr = %p\n", tSNL,
    (readingStrs+tOTL+tONL));
    char *tSL[tSLL];
    memcpy(tSL,(readingStrs+tOTL+tONL+tSNL),tSLL);
    printf("tSLL = %d and sL ptr = %p\n", tSLL,
    (readingStrs+tOTL+tONL+tSNL));
    char *tID[tIDL];
    memcpy(tID,(readingStrs+tOTL+tONL+tSNL+tSLL),tIDL);
    printf("tIDL = %d and iD ptr = %p\n", tIDL,
    (readingStrs+tOTL+tONL+tSNL+tSLL));
    char tMD[tMDL];
    memcpy(tMD,(readingStrs+tOTL+tONL+tSNL+tSLL+tIDL),tMDL);
    printf("tMDL = %d and mD ptr = %p\n", tMDL,
    (readingStrs+tOTL+tONL+tSNL+tSLL+tIDL));

    printf("oT = %s\n",tOT);
    printf("oN = %s\n",tON);
    printf("sN = %s\n",tSN);
    printf("sL = %s\n",tSL);
    printf("iD = %s\n",tID);
    printf("mD = %s\n",tMD);

    //do smth with these variables now

    }

    any ideas where my c++ knowledge is slipping?
    thank you for your help
    nass
    nass, Nov 14, 2006
    #1
    1. Advertising

  2. nass

    mlimber Guest

    nass wrote:
    > hello everyone, i have a bit of problem reading char * strings from a
    > buffer (a shared memory, pointed to by 'file_memory').
    > basically i have a structure in memory 'ShMem' that can be accessed by
    > 2 applications (or will be at least when it is done).
    > the structure is declared in the procedure under the pointer infoVar.
    > members tXXL are integer lengths of the strings that as all saved
    > (concatenated) at address of oAndS_str, which is of type char.
    > i do not get the right values back however, and i wonder if the tXX
    > 'reconstruction strings' are assigned values properly with memcpy.
    >
    > void readingTheShMem()
    > {
    > int tOTL=0;
    > int tONL=0;
    > int tSNL=0;
    > int tSLL=0;
    > int tIDL=0;
    > int tMDL=0;
    > int readingLength;
    >
    > //lock the file for writing
    > memset (&lock, 0, sizeof(lock));


    I hope lock is a POD type
    (http://www.parashift.com/c -faq-lite/intrinsic-types.html#faq-26.7),
    or else you're playing with fire when using memset.

    > lock.l_type = F_WRLCK;
    > fcntl (fd, F_SETLKW, &lock);
    >
    > struct ShMem *infoVar=(ShMem*)((char*)file_memory);
    >
    > tOTL = infoVar->oTL;
    > tONL = infoVar->oNL;
    > tSNL = infoVar->sNL;
    > tSLL = infoVar->sLL;
    > tIDL = infoVar->iDL;
    > tMDL = infoVar->mDL;
    > readingLength = tOTL + tONL + tSNL + tSLL + tIDL + tMDL ;
    > char *readingStrs[readingLength];


    This is not valid C++. The array length must be constant.

    > printf("reading length = %d\n", readingLength);
    > printf("the infoVar->oAndS_str reading points
    > to=%p\n",&(infoVar->oAndS_str));
    > memcpy(readingStrs, &(infoVar->oAndS_str),
    > readingLength);


    I'm not sure what you're trying to do here, but it looks mighty
    suspicious. readingStrs is an array of *pointers*. Did you mean for it
    to be a string of characters or a two dimensional array of characters
    (i.e., an array of character strings)?

    >
    > //unlock the file to allow access
    > lock.l_type = F_UNLCK;
    > fcntl (fd, F_SETLKW, &lock);
    >
    > char *tOT[tOTL]; memcpy(tOT,readingStrs,tOTL);
    > printf("tOTL = %d and oT ptr = %p\n", tOTL, readingStrs);
    > char *tON[tONL]; memcpy(tON,(readingStrs+tOTL),tONL);
    > printf("tONL = %d and oN ptr = %p\n", tONL,
    > (readingStrs+tOTL));
    > char *tSN[tSNL];
    > memcpy(tSN,(readingStrs+tOTL+tONL),tSNL);
    > printf("tSNL = %d and sN ptr = %p\n", tSNL,
    > (readingStrs+tOTL+tONL));
    > char *tSL[tSLL];
    > memcpy(tSL,(readingStrs+tOTL+tONL+tSNL),tSLL);
    > printf("tSLL = %d and sL ptr = %p\n", tSLL,
    > (readingStrs+tOTL+tONL+tSNL));
    > char *tID[tIDL];
    > memcpy(tID,(readingStrs+tOTL+tONL+tSNL+tSLL),tIDL);
    > printf("tIDL = %d and iD ptr = %p\n", tIDL,
    > (readingStrs+tOTL+tONL+tSNL+tSLL));
    > char tMD[tMDL];
    > memcpy(tMD,(readingStrs+tOTL+tONL+tSNL+tSLL+tIDL),tMDL);
    > printf("tMDL = %d and mD ptr = %p\n", tMDL,
    > (readingStrs+tOTL+tONL+tSNL+tSLL+tIDL));
    >
    > printf("oT = %s\n",tOT);
    > printf("oN = %s\n",tON);
    > printf("sN = %s\n",tSN);
    > printf("sL = %s\n",tSL);
    > printf("iD = %s\n",tID);
    > printf("mD = %s\n",tMD);
    >
    > //do smth with these variables now
    >
    > }
    >
    > any ideas where my c++ knowledge is slipping?


    Use std::string rather than manual character arrays when you can
    (http://www.parashift.com/c -faq-lite/containers.html#faq-34.1). In
    this case, you'll probably want to store the data in raw arrays in the
    shared mem but copy it into local std::strings.

    Cheers! --M
    mlimber, Nov 14, 2006
    #2
    1. Advertising

  3. nass

    nass Guest

    hello and thank you for your help.
    using std::string is not an option since these char * values i want
    later to assign to a QString class (trolltech's Qt library to
    manipulate strings unicode utf-16 bits). and the QString construct can
    accept const char * but not string& ...

    however, lets stick to the fact i did manage to retrieve the data from
    the buffer.. i.e. with printf i can see the expected output on the
    console. the thing is in the code i dont take into account anywhere
    (among the chars tOT, tON, tSN, tSL, tID and tMD that is) for a NULL
    terminator.. or does it do it automatically?

    cause now i have problem with the transition from const char * to
    QString and i wonder if it could be that the QString constructor does
    not find the NULL terminators.
    so i m asking if u think that the \0 character is there in my code the
    way i have written it or not..
    thank you for your help
    nass

    mlimber wrote:
    > nass wrote:
    > > hello everyone, i have a bit of problem reading char * strings from a
    > > buffer (a shared memory, pointed to by 'file_memory').
    > > basically i have a structure in memory 'ShMem' that can be accessed by
    > > 2 applications (or will be at least when it is done).
    > > the structure is declared in the procedure under the pointer infoVar.
    > > members tXXL are integer lengths of the strings that as all saved
    > > (concatenated) at address of oAndS_str, which is of type char.
    > > i do not get the right values back however, and i wonder if the tXX
    > > 'reconstruction strings' are assigned values properly with memcpy.
    > >
    > > void readingTheShMem()
    > > {
    > > int tOTL=0;
    > > int tONL=0;
    > > int tSNL=0;
    > > int tSLL=0;
    > > int tIDL=0;
    > > int tMDL=0;
    > > int readingLength;
    > >
    > > //lock the file for writing
    > > memset (&lock, 0, sizeof(lock));

    >
    > I hope lock is a POD type
    > (http://www.parashift.com/c -faq-lite/intrinsic-types.html#faq-26.7),
    > or else you're playing with fire when using memset.
    >
    > > lock.l_type = F_WRLCK;
    > > fcntl (fd, F_SETLKW, &lock);
    > >
    > > struct ShMem *infoVar=(ShMem*)((char*)file_memory);
    > >
    > > tOTL = infoVar->oTL;
    > > tONL = infoVar->oNL;
    > > tSNL = infoVar->sNL;
    > > tSLL = infoVar->sLL;
    > > tIDL = infoVar->iDL;
    > > tMDL = infoVar->mDL;
    > > readingLength = tOTL + tONL + tSNL + tSLL + tIDL + tMDL ;
    > > char *readingStrs[readingLength];

    >
    > This is not valid C++. The array length must be constant.
    >
    > > printf("reading length = %d\n", readingLength);
    > > printf("the infoVar->oAndS_str reading points
    > > to=%p\n",&(infoVar->oAndS_str));
    > > memcpy(readingStrs, &(infoVar->oAndS_str),
    > > readingLength);

    >
    > I'm not sure what you're trying to do here, but it looks mighty
    > suspicious. readingStrs is an array of *pointers*. Did you mean for it
    > to be a string of characters or a two dimensional array of characters
    > (i.e., an array of character strings)?
    >
    > >
    > > //unlock the file to allow access
    > > lock.l_type = F_UNLCK;
    > > fcntl (fd, F_SETLKW, &lock);
    > >
    > > char *tOT[tOTL]; memcpy(tOT,readingStrs,tOTL);
    > > printf("tOTL = %d and oT ptr = %p\n", tOTL, readingStrs);
    > > char *tON[tONL]; memcpy(tON,(readingStrs+tOTL),tONL);
    > > printf("tONL = %d and oN ptr = %p\n", tONL,
    > > (readingStrs+tOTL));
    > > char *tSN[tSNL];
    > > memcpy(tSN,(readingStrs+tOTL+tONL),tSNL);
    > > printf("tSNL = %d and sN ptr = %p\n", tSNL,
    > > (readingStrs+tOTL+tONL));
    > > char *tSL[tSLL];
    > > memcpy(tSL,(readingStrs+tOTL+tONL+tSNL),tSLL);
    > > printf("tSLL = %d and sL ptr = %p\n", tSLL,
    > > (readingStrs+tOTL+tONL+tSNL));
    > > char *tID[tIDL];
    > > memcpy(tID,(readingStrs+tOTL+tONL+tSNL+tSLL),tIDL);
    > > printf("tIDL = %d and iD ptr = %p\n", tIDL,
    > > (readingStrs+tOTL+tONL+tSNL+tSLL));
    > > char tMD[tMDL];
    > > memcpy(tMD,(readingStrs+tOTL+tONL+tSNL+tSLL+tIDL),tMDL);
    > > printf("tMDL = %d and mD ptr = %p\n", tMDL,
    > > (readingStrs+tOTL+tONL+tSNL+tSLL+tIDL));
    > >
    > > printf("oT = %s\n",tOT);
    > > printf("oN = %s\n",tON);
    > > printf("sN = %s\n",tSN);
    > > printf("sL = %s\n",tSL);
    > > printf("iD = %s\n",tID);
    > > printf("mD = %s\n",tMD);
    > >
    > > //do smth with these variables now
    > >
    > > }
    > >
    > > any ideas where my c++ knowledge is slipping?

    >
    > Use std::string rather than manual character arrays when you can
    > (http://www.parashift.com/c -faq-lite/containers.html#faq-34.1). In
    > this case, you'll probably want to store the data in raw arrays in the
    > shared mem but copy it into local std::strings.
    >
    > Cheers! --M
    nass, Nov 14, 2006
    #3
  4. * nass:
    > [top-posting and overquoting].


    Please use some time to get familiar with the conventions in this group.

    TIA.,

    Alf, The Network Police.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Nov 14, 2006
    #4
  5. nass

    Howard Guest

    "nass" <> wrote in message
    news:...
    > hello and thank you for your help.
    > using std::string is not an option since these char * values i want
    > later to assign to a QString class (trolltech's Qt library to
    > manipulate strings unicode utf-16 bits). and the QString construct can
    > accept const char * but not string& ...
    >


    The std::string class has a member function c_str() which will give you what
    you need.

    > however, lets stick to the fact i did manage to retrieve the data from
    > the buffer.. i.e. with printf i can see the expected output on the
    > console. the thing is in the code i dont take into account anywhere
    > (among the chars tOT, tON, tSN, tSL, tID and tMD that is) for a NULL
    > terminator.. or does it do it automatically?
    >
    > cause now i have problem with the transition from const char * to
    > QString and i wonder if it could be that the QString constructor does
    > not find the NULL terminators.
    > so i m asking if u think that the \0 character is there in my code the
    > way i have written it or not..
    > thank you for your help
    > nass
    >


    Did you fix the problems with the code that you posted earlier? It's simply
    not legal to declare an array with a variable as the array size (even though
    some compilers might allow it).

    If you want an array of char, then declare an array of char with constant
    size, like this:
    char a[CONST_SIZE]; // (where CONST_SIZE is a compile-time constant)

    or, dynamically allocate it like this:
    char* pA = new char[non_const_size];

    or better, use std::string.

    When you declare an array like this:
    char* a[CONST_SIZE];
    you're specifying an array of char* pointers, NOT an array of char!

    And doing this:
    char* a[non_const_size];
    is simply illegal. (And if your compiler allows it, then it STILL declares
    an array of pointers, not an array of char.)

    Regarding NULL-terminators for C-style strings: using memcpy will only copy
    a NULL-terminator if there is already one in the source (and it doesn't
    matter where in the data that 0 is, it will copy the amount specified,
    regardless of the presence of one or more 0s).

    You need to add a NULL-terminator yourself if you use memcpy. (And you need
    to remember to allocate room for that NULL-terminator in your destination
    array!)

    Using strncpy is also a possible solution. (But again, std::string is
    better.)

    -Howard
    Howard, Nov 14, 2006
    #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.
Similar Threads
  1. Raja
    Replies:
    12
    Views:
    24,347
    John Harrison
    Jun 21, 2004
  2. imma
    Replies:
    5
    Views:
    297
    sathyashrayan
    Nov 11, 2005
  3. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    735
    Malcolm
    Jun 24, 2006
  4. Replies:
    2
    Views:
    587
    sergejusz
    Mar 26, 2007
  5. Neal Becker

    buffer creates only read-only buffer?

    Neal Becker, Jan 8, 2009, in forum: Python
    Replies:
    0
    Views:
    400
    Neal Becker
    Jan 8, 2009
Loading...

Share This Page