unable to read char * strings from a buffer

N

nass

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
 
M

mlimber

nass said:
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
 
N

nass

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
nass said:
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
 
H

Howard

nass said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top