By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,605 Members | 1,391 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,605 IT Pros & Developers. It's quick & easy.

unable to read char * strings from a buffer

P: n/a
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

Nov 14 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
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

Nov 14 '06 #2

P: n/a
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
Nov 14 '06 #3

P: n/a
* 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?
Nov 14 '06 #4

P: n/a

"nass" <at**************@gmail.comwrote in message
news:11**********************@m73g2000cwd.googlegr 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
Nov 14 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.