Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > unable to read char * strings from a buffer

Reply
Thread Tools

unable to read char * strings from a buffer

 
 
nass
Guest
Posts: n/a
 
      11-14-2006
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

 
Reply With Quote
 
 
 
 
mlimber
Guest
Posts: n/a
 
      11-14-2006
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-lit...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-lit...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

 
Reply With Quote
 
 
 
 
nass
Guest
Posts: n/a
 
      11-14-2006
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-lit...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-lit...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


 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      11-14-2006
* 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?
 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      11-14-2006

"nass" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> 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


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
buffer creates only read-only buffer? Neal Becker Python 0 01-08-2009 01:58 AM
removing newline character from the buffer read by fgets junky_fellow@yahoo.co.in C Programming 16 11-28-2006 10:44 PM
Strings, Strings and Damned Strings Ben C Programming 14 06-24-2006 05:09 AM
Read strings from a one dimensional buffer... imma C Programming 5 11-11-2005 09:42 AM
How to know the buffer size and increase buffer size in c++ Raja C++ 12 06-21-2004 06:21 PM



Advertisments