Could a struct with size 44 bytes point always points to a char array with size 2024 bytes?

E

eagle_jyjh

For example:

the
msg = temp_buf;
is alwawys ok?

//test_msg.cpp
struct msg_head
{
char a01[4];
char a02[4];
char a03[4];
char a04[4];
char a05[4];
char a06[4];
char a07[4];
char a08[4];
char a09[4];
char a10[4];
char a11[4];

};

int main(void)
{
struct msg_head * msg;
char *p_temp_buf = new char[2024];
...
msg = (struct msg_head *)p_temp_buf;
...
delete p_temp_buf;
return 0;
}
 
E

eagle_jyjh

or
the following is always OK?

int main(void)
{
struct msg_head * msg;
char temp_buf[2024];
...
msg = (struct msg_head *)temp_buf;
...

return 0;
}
 
B

Ben Pope

For example:

the
msg = temp_buf;
is alwawys ok?

//test_msg.cpp
struct msg_head
{
char a01[4];
char a02[4];
char a03[4];
char a04[4];
char a05[4];
char a06[4];
char a07[4];
char a08[4];
char a09[4];
char a10[4];
char a11[4];

};

int main(void)
{
struct msg_head * msg;
char *p_temp_buf = new char[2024];
...
msg = (struct msg_head *)p_temp_buf;

If it was "ok", you wouldn't need the cast.

What are you trying to achieve?

Ben Pope
 
R

Richard G. Riley

For example:

the
msg = temp_buf;
is alwawys ok?

//test_msg.cpp
struct msg_head
{
char a01[4];
char a02[4];
char a03[4];
char a04[4];
char a05[4];
char a06[4];
char a07[4];
char a08[4];
char a09[4];
char a10[4];
char a11[4];

};

int main(void)
{
struct msg_head * msg;
char *p_temp_buf = new char[2024];
...
msg = (struct msg_head *)p_temp_buf;
...
delete p_temp_buf;
return 0;
}

While it is "nasty", it will work. I can see no potential for your
struct size to ever increase over 2024 "char"s due to , say,
alignment.

But why? Whyt are you trying to do? Save "malloc" time by using a
global buffer for allsorts of temproary data?
 
P

Pavel

For example:

the
msg = temp_buf;
is alwawys ok?

//test_msg.cpp
struct msg_head
{
char a01[4];
char a02[4];
char a03[4];
char a04[4];
char a05[4];
char a06[4];
char a07[4];
char a08[4];
char a09[4];
char a10[4];
char a11[4];

};

int main(void)
{
struct msg_head * msg;
char *p_temp_buf = new char[2024];
...
msg = (struct msg_head *)p_temp_buf;
...
delete p_temp_buf;
return 0;
}
As per the Standard, it is probably undefined behavior. In practice, it
is "ok" in the sense you will not access wrong memory. The structure may
not have its normal (for the compiler/architecture) alignment though
(this especially often will happen with your second example where you
use the buffer on stack). This should not be a problem if you operate
with the character fields only but may be a problem (like bus error) if
you, for example, assign to or even from such structure as a whole and
the compiler generates some optimized code. The following hack would
take care of this problem, most of the time for 64- or less- bit
architectures:

const int WHOLE_LENGTH = 2031;
const int GUARANTEED_LENGTH = 2024;
char *p_allocated_temp_buf = new char[WHOLE_LENGTH];
char *p_temp_buf = ((p_allocated_temp_buf - 1) >> 3) << 3;
if(p_temp_buf != p_allocated_temp_buf) p_temp_buf += 8;
// ... use p_temp_buf for up to Guaranteed_length
delete [] p_allocated_temp_buf;
 
J

Jack Klein

For example:

the
msg = temp_buf;
is alwawys ok?

//test_msg.cpp
struct msg_head
{
char a01[4];
char a02[4];
char a03[4];
char a04[4];
char a05[4];
char a06[4];
char a07[4];
char a08[4];
char a09[4];
char a10[4];
char a11[4];

};

int main(void)
{
struct msg_head * msg;
char *p_temp_buf = new char[2024];
...
msg = (struct msg_head *)p_temp_buf;
...
delete p_temp_buf;
return 0;
}
As per the Standard, it is probably undefined behavior. In practice, it
is "ok" in the sense you will not access wrong memory. The structure may
not have its normal (for the compiler/architecture) alignment though
(this especially often will happen with your second example where you
use the buffer on stack). This should not be a problem if you operate
with the character fields only but may be a problem (like bus error) if
you, for example, assign to or even from such structure as a whole and
the compiler generates some optimized code. The following hack would
take care of this problem, most of the time for 64- or less- bit
architectures:

const int WHOLE_LENGTH = 2031;
const int GUARANTEED_LENGTH = 2024;
char *p_allocated_temp_buf = new char[WHOLE_LENGTH];
char *p_temp_buf = ((p_allocated_temp_buf - 1) >> 3) << 3;

If you think there is a C++ compiler in existence that will compile
the line above, I think you are mistaken. Even if you can get it to
compile, the subexpression "p_allocated_temp_buf - 1" invokes
undefined behavior all by itself. Decrementing a pointer to the start
of allocated space is undefined.
if(p_temp_buf != p_allocated_temp_buf) p_temp_buf += 8;
// ... use p_temp_buf for up to Guaranteed_length
delete [] p_allocated_temp_buf;

Complete rubbish.
 
P

Pavel

Jack Klein wrote:
....
If you think there is a C++ compiler in existence that will compile
the line above, I think you are mistaken. Even if you can get it to
compile, the subexpression "p_allocated_temp_buf - 1" invokes
undefined behavior all by itself. Decrementing a pointer to the start
of allocated space is undefined. ....


Complete rubbish.
A bit gross even if formally true. I just wanted to demonstrate the
idea. The working code follows (the behavior is, of course theoretically
"undefined" as I mentioned in my first post, but in practice workable
and even pretty well portable):

#include <iostream>

using namespace std;

char *align_forward(char *ptr, unsigned n) {
if(!ptr) return ptr;
return (char *)(((((reinterpret_cast<unsigned long>(ptr) - 1) >> n) +
1) << n));
}

int main() {
const int WHOLE_LENGTH = 2031;
const int GUARANTEED_LENGTH = 2024;
char *p_allocated_temp_buf = new char[WHOLE_LENGTH];
char *p_temp_buf = align_forward(p_allocated_temp_buf, 3);
cout << "aligned " << (void *) (p_allocated_temp_buf) << "="
<< (void *) align_forward(p_allocated_temp_buf, 3) << ", "
<< (void *) (p_allocated_temp_buf + 1) << "="
<< (void *) align_forward(p_allocated_temp_buf + 1, 3) << endl;
delete [] p_allocated_temp_buf;
return 0;
}
 
M

Michiel.Salters

Pavel said:
For example:

the
msg = temp_buf;
is alwawys ok?

//test_msg.cpp
struct msg_head
{
char a01[4]; //... (more char[4]s)
};

int main(void)
{
struct msg_head * msg;
char *p_temp_buf = new char[2024];
...
msg = (struct msg_head *)p_temp_buf;
...
delete p_temp_buf;
return 0;
}
As per the Standard, it is probably undefined behavior. In practice, it
is "ok" in the sense you will not access wrong memory. The structure may
not have its normal (for the compiler/architecture) alignment ..

Wrong. new char[] must return memory that's suitably allocated for any
type.
The reason is that char also serves as C++'s byte type. (Besides, since
the
structure only has char[]s, I expect most compilers to align it like a
char[] )
HTH,
Michiel Salters.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top