Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

write a four byte integer to a memory region allocated as (char)

23 views
Skip to first unread message

rlc

unread,
Jun 12, 2009, 10:31:26 AM6/12/09
to
Hey guys,

I have a buffer in memory allocated as 1 byte chars. I need to
periodically write a four byte integer number into this structure.

int nextIndex = 1024;
char *buffer = malloc(sizeBuffer);
buffer[0-4] = nextIndex; //meaning that the first four bytes of buffer
will contain the index, but how do I do this?
If I just write buffer[0] = nextIndex;
then nextIndex will be truncated to one byte. And I can't index the
buffer with integers for a couple of different reasons.

Thanks

Jens Thoms Toerring

unread,
Jun 12, 2009, 10:58:22 AM6/12/09
to
rlc <rcl...@gmail.com> wrote:
> I have a buffer in memory allocated as 1 byte chars.

That's a bit of a tautology - at least in C a char is always
one byte;-)

> I need to
> periodically write a four byte integer number into this structure.

> int nextIndex = 1024;
> char *buffer = malloc(sizeBuffer);
> buffer[0-4] = nextIndex; //meaning that the first four bytes of buffer
> will contain the index, but how do I do this?
> If I just write buffer[0] = nextIndex;
> then nextIndex will be truncated to one byte.

Did you try

* ( int * ) buffer = nextIndex;

or, if you don't like that

memcpy( buffer, &nextIndex, sizeof nextIndex );

The latter method is required if buffer shouldn't be
properly aligned for int wide access - but as long as
buffer is an address returned by malloc() etc. it's
not an issue. But if you try do e.g.

* ( int * ) ( buffer + 15 ) = some_int_value;

you may get in trouble on a numberof architectures.

Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

rlc

unread,
Jun 12, 2009, 11:01:54 AM6/12/09
to

Excellent, thank you. * ( int * ) buffer = nextIndex; was exactly
what I needed.

Willem

unread,
Jun 12, 2009, 11:02:39 AM6/12/09
to
rlc wrote:
) Hey guys,
)
) I have a buffer in memory allocated as 1 byte chars. I need to
) periodically write a four byte integer number into this structure.
)
) int nextIndex = 1024;
) char *buffer = malloc(sizeBuffer);
) buffer[0-4] = nextIndex; //meaning that the first four bytes of buffer
) will contain the index, but how do I do this?
) If I just write buffer[0] = nextIndex;
) then nextIndex will be truncated to one byte. And I can't index the
) buffer with integers for a couple of different reasons.

Do you want it little-endian/big endian/etc or machine-endian ?

Or, to put it differently: what is the purpose of writing these integers ?

From the fact that you want four-byte integers, I guess you want
specific-endian. In which case you simply split up your integer
into four bytes (using arithmetic operators, or shifts and ands)
and assign them to the four buffer positions separately. Big- or
little endian is then simply a matter of which order you assign.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Ben Bacarisse

unread,
Jun 12, 2009, 11:03:20 AM6/12/09
to
rlc <rcl...@gmail.com> writes:

I am sure you can! In fact, doing so is the easiest way to put an int
where you want it:

int *now_index_as_int = (void *)buffer;
now_index_as_int[0] = nextIndex;

This is a long-winded version of:

*(int *)buffer = nextIndex;

You will get into trouble if the pointer is not properly aligned, but
pointers returned from malloc always will be. If you need to do this
in a relatively portable way (even when the pointer may not be
correctly aligned) you need to pack the int byte-by-byte. This lets
you choose the byte-order which is important if the buffer is
going to be sent somewhere where it might be read by different
hardware:

buffer[0] = nextIndex;
buffer[1] = nextIndex >> 8;
buffer[2] = nextIndex >> 16;
buffer[3] = nextIndex >> 24;

for example. The best way to avoid surprises here is to make all the
types unsigned.

--
Ben.

blargg

unread,
Jun 12, 2009, 11:27:36 AM6/12/09
to
Ben Bacarisse wrote:
> rlc <rcl...@gmail.com> writes:
> > I have a buffer in memory allocated as 1 byte chars. I need to
> > periodically write a four byte integer number into this structure.
> >
> > int nextIndex = 1024;
> > char *buffer = malloc(sizeBuffer);
> > buffer[0-4] = nextIndex; //meaning that the first four bytes of buffer

First four or five? 0, 1, 2, 3, 4 is five indicies.

> > will contain the index, but how do I do this?
> > If I just write buffer[0] = nextIndex;
> > then nextIndex will be truncated to one byte. And I can't index the
> > buffer with integers for a couple of different reasons.
>
> I am sure you can! In fact, doing so is the easiest way to put an int
> where you want it:
>
> int *now_index_as_int = (void *)buffer;
> now_index_as_int[0] = nextIndex;

Uhhh, he said four bytes, not sizeof(int) bytes. On one of my compilers,
this would only write two bytes.

> This is a long-winded version of:
>
> *(int *)buffer = nextIndex;
>
> You will get into trouble if the pointer is not properly aligned, but
> pointers returned from malloc always will be. If you need to do this
> in a relatively portable way (even when the pointer may not be
> correctly aligned) you need to pack the int byte-by-byte. This lets
> you choose the byte-order which is important if the buffer is
> going to be sent somewhere where it might be read by different
> hardware:
>
> buffer[0] = nextIndex;
> buffer[1] = nextIndex >> 8;
> buffer[2] = nextIndex >> 16;
> buffer[3] = nextIndex >> 24;
>
> for example. The best way to avoid surprises here is to make all the
> types unsigned.

Still a problem, since buffer is a char*. He should make it a uint8_t*,
which ensures it's 8 bits per byte as he's assuming:

uint8_t* p = malloc( 4 );
p [0] = nextIndex >> 0 & 0xFF;
p [1] = nextIndex >> 8 & 0xFF;
p [2] = nextIndex >> 16 & 0xFF;
p [3] = nextIndex >> 24 & 0xFF;

(the masks eliminate warnings on some compilers, and make it clear to
everyone that truncation is occurring)

pete

unread,
Jun 12, 2009, 11:39:08 AM6/12/09
to
blargg wrote:
> Ben Bacarisse wrote:
>> rlc <rcl...@gmail.com> writes:
>>> I have a buffer in memory allocated as 1 byte chars. I need to
>>> periodically write a four byte integer number into this structure.
>>>
>>> int nextIndex = 1024;
>>> char *buffer = malloc(sizeBuffer);
>>> buffer[0-4] = nextIndex; //meaning that the first four bytes of buffer
>
> First four or five? 0, 1, 2, 3, 4 is five indicies.
>
>>> will contain the index, but how do I do this?
>>> If I just write buffer[0] = nextIndex;
>>> then nextIndex will be truncated to one byte. And I can't index the
>>> buffer with integers for a couple of different reasons.
>> I am sure you can! In fact, doing so is the easiest way to put an int
>> where you want it:
>>
>> int *now_index_as_int = (void *)buffer;
>> now_index_as_int[0] = nextIndex;
>
> Uhhh, he said four bytes, not sizeof(int) bytes. On one of my compilers,
> this would only write two bytes.

He said "four byte integer".

I think the task is to write the integer value,
and he is also saying that he has four byte integers.

--
pete

rlc

unread,
Jun 12, 2009, 12:26:13 PM6/12/09
to
Yeah, it should be buffer[0-3]. On my architecture int is four bytes.
Specifically what I was trying to do is to take a long segment of byte
data and periodically write header information to it so that I can
split it up to be processed on a parallel architecture. The header info
(the four byte ints) point to the beginning of sub-sections so that
they can be processed as a cohesive unit.

for instance, I want my byte stream to appear as thus:

10aaaaaa6bb8cccc

where the numbers are four byte ints and the letters are arbitrary one
byte symbols. The integers point to the beginning of the next
segment, denoting the length of a subsection. The 10 indicates that
the first subsection is 10 bytes in length and the subsection begins
at buffer[10]. In actuality these subsections are going to be much
longer, which is the reason I need a greater number of bits than a
single byte.

Best regards to everyone and thanks for the illuminating responses. I
actually didn't realize that you could cast a memory buffer to change
the indexing. I knew bit shifting would probably work, but I always
manage to screw things up and introduce bugs, plus I save cycles by
casting because it is done at compile time, right?

Ben Bacarisse

unread,
Jun 12, 2009, 4:58:16 PM6/12/09
to
blarg...@gishpuppy.com (blargg) writes:

> Ben Bacarisse wrote:
<snip>


>> int *now_index_as_int = (void *)buffer;
>> now_index_as_int[0] = nextIndex;
>
> Uhhh, he said four bytes, not sizeof(int) bytes. On one of my compilers,
> this would only write two bytes.

Picky! I guessed he wanted an int and it just happens to be 4 bytes.

<snip>
>> ... If you need to do this


>> in a relatively portable way (even when the pointer may not be
>> correctly aligned) you need to pack the int byte-by-byte. This lets
>> you choose the byte-order which is important if the buffer is
>> going to be sent somewhere where it might be read by different
>> hardware:
>>
>> buffer[0] = nextIndex;
>> buffer[1] = nextIndex >> 8;
>> buffer[2] = nextIndex >> 16;
>> buffer[3] = nextIndex >> 24;
>>
>> for example. The best way to avoid surprises here is to make all the
>> types unsigned.
>
> Still a problem, since buffer is a char*.

Well, I said "all types". I wanted that to include the buffer.

> He should make it a uint8_t*,
> which ensures it's 8 bits per byte as he's assuming:

I am less sure about the advantages of using uint8_t. I agree it is
good way to stop the program working (compiling even) on systems that
violate an assumption, but depending on what you are doing with the
8-bit parts, you might get away with it even when char is wider than
8.

<snip>
--
Ben.

Tor Rustad

unread,
Jun 12, 2009, 6:13:56 PM6/12/09
to
rlc wrote:
> Hey guys,
>
> I have a buffer in memory allocated as 1 byte chars. I need to
> periodically write a four byte integer number into this structure.

char *buf;
size_t max_buf = 4;
int i = 1024;

buf = malloc(max_buf);
if (NULL == buf) {
...
}

assert(max_buf >= sizeof i);
memcpy(buf, &i, sizeof i);

--
Tor <echo bwz...@wvtqvm.vw | tr i-za-h a-z>

Barry Schwarz

unread,
Jun 12, 2009, 8:29:11 PM6/12/09
to
On Fri, 12 Jun 2009 08:01:54 -0700 (PDT), rlc <rcl...@gmail.com>
wrote:

>On Jun 12, 8:58�am, j...@toerring.de (Jens Thoms Toerring) wrote:
>> rlc <rcl...@gmail.com> wrote:
>> > I have a buffer in memory allocated as 1 byte chars.
>>
>> That's a bit of a tautology - at least in C a char is always
>> one byte;-)
>>
>> > I need to
>> > periodically write a four byte integer number into this structure.
>> > int nextIndex = 1024;
>> > char *buffer = malloc(sizeBuffer);
>> > buffer[0-4] = nextIndex; //meaning that the first four bytes of buffer
>> > will contain the index, but how do I do this?
>> > If I just write buffer[0] = nextIndex;
>> > then nextIndex will be truncated to one byte.
>>
>> Did you try
>>
>> * ( int * ) buffer = nextIndex;
>>
>> or, if you don't like that
>>
>> memcpy( buffer, &nextIndex, sizeof nextIndex );
>>
>> The latter method is required if buffer shouldn't be
>> properly aligned for int wide access - but as long as
>> buffer is an address returned by malloc() etc. it's
>> not an issue. But if you try do e.g.
>>
>> * ( int * ) ( buffer + 15 ) = some_int_value;
>>
>> you may get in trouble on a numberof architectures.

>> � �\__________________________ � � �http://toerring.de


>
>Excellent, thank you. * ( int * ) buffer = nextIndex; was exactly
>what I needed.

Did you not read the caveat? It will work for a buffer that has been
dynamically allocated as in your example but may fail miserably if you
try with a defined buffer.

--
Remove del for email

Barry Schwarz

unread,
Jun 12, 2009, 8:29:11 PM6/12/09
to
On Fri, 12 Jun 2009 10:39:08 -0500, pete <pfi...@mindspring.com>
wrote:

>blargg wrote:
>> Ben Bacarisse wrote:
>>> rlc <rcl...@gmail.com> writes:
>>>> I have a buffer in memory allocated as 1 byte chars. I need to
>>>> periodically write a four byte integer number into this structure.
>>>>
>>>> int nextIndex = 1024;
>>>> char *buffer = malloc(sizeBuffer);
>>>> buffer[0-4] = nextIndex; //meaning that the first four bytes of buffer
>>
>> First four or five? 0, 1, 2, 3, 4 is five indicies.
>>
>>>> will contain the index, but how do I do this?
>>>> If I just write buffer[0] = nextIndex;
>>>> then nextIndex will be truncated to one byte. And I can't index the
>>>> buffer with integers for a couple of different reasons.
>>> I am sure you can! In fact, doing so is the easiest way to put an int
>>> where you want it:
>>>
>>> int *now_index_as_int = (void *)buffer;
>>> now_index_as_int[0] = nextIndex;
>>
>> Uhhh, he said four bytes, not sizeof(int) bytes. On one of my compilers,
>> this would only write two bytes.
>
>He said "four byte integer".

long is a four byte integer.

>
>I think the task is to write the integer value,
>and he is also saying that he has four byte integers.

--
Remove del for email

James Kuyper

unread,
Jun 12, 2009, 9:04:05 PM6/12/09
to
Barry Schwarz wrote:
...

> long is a four byte integer.

Not necessarily.

blargg

unread,
Jun 13, 2009, 12:28:55 AM6/13/09
to
Barry Schwarz wrote:
> On Fri, 12 Jun 2009 10:39:08 -0500, pete <pfi...@mindspring.com>
> wrote:
>
> >blargg wrote:
> >> Ben Bacarisse wrote:
> >>> rlc <rcl...@gmail.com> writes:
> >>>> I have a buffer in memory allocated as 1 byte chars. I need to
> >>>> periodically write a four byte integer number into this structure.
[...]

> >>> int *now_index_as_int = (void *)buffer;
> >>> now_index_as_int[0] = nextIndex;
> >>
> >> Uhhh, he said four bytes, not sizeof(int) bytes. On one of my compilers,
> >> this would only write two bytes.
> >
> > He said "four byte integer".
>
> long is a four byte integer.

Not in some 64-bit Linux platforms. It is guaranteed to be at *minimum*
a four *octet* integer, though (not necessarily four bytes, since on
some platforms a byte has 16 bits, like many DSPs, where sizeof(long)<4).

David Thompson

unread,
Jul 1, 2009, 1:30:02 AM7/1/09
to
On Fri, 12 Jun 2009 09:26:13 -0700 (PDT), rlc <rcl...@gmail.com>
wrote:

> Yeah, it should be buffer[0-3]. On my architecture int is four bytes.


> Specifically what I was trying to do is to take a long segment of byte
> data and periodically write header information to it so that I can
> split it up to be processed on a parallel architecture. The header info

Is the splitter part of the architecture, or a separate front-end or
manager or whatever? In particular, do you KNOW they are the same
endian (as well as the same size = 4 bytes and the same bytesize,
and no differences in padding -- or just no padding at all)?

> (the four byte ints) point to the beginning of sub-sections so that
> they can be processed as a cohesive unit.
>
> for instance, I want my byte stream to appear as thus:
>
> 10aaaaaa6bb8cccc
>
> where the numbers are four byte ints and the letters are arbitrary one
> byte symbols. The integers point to the beginning of the next
> segment, denoting the length of a subsection. The 10 indicates that
> the first subsection is 10 bytes in length and the subsection begins

IAYM the _next_ subsection, really the next count, begins at 10.

> at buffer[10]. In actuality these subsections are going to be much
> longer, which is the reason I need a greater number of bits than a
> single byte.
>

This brings up the already-mentioned issue of alignment. If this
buffer is (at the beginning of) malloc'ed space, it is correctly
aligned for any C datatype -- including int. But buff+10 bytes is NOT
guaranteed to be aligned correctly, and for some systems it isn't.

If your system doesn't have alignment requirements, you're OK.
If it has only a 'soft' requirement (misaligned access still works but
is slower) and the amount of accesses to these count fields is small
(enough) compared to your other processing, still OK. Otherwise, you
have two choices:

- do the byte-by-byte access, either explicitly or with memcpy. This
will probably be a little slower on every count, although compared to
the rest of your processing it is likely negligible.

- move each count position to the next aligned location, wasting up to
3 bytes (padding) as needed. If the data is already large, as you say,
wasting say .0001% or whatever of the buffer space may be OK.

> Best regards to everyone and thanks for the illuminating responses. I
> actually didn't realize that you could cast a memory buffer to change
> the indexing. I knew bit shifting would probably work, but I always
> manage to screw things up and introduce bugs, plus I save cycles by
> casting because it is done at compile time, right?

Not necessarily. But most machines nowadays are byte addressed, so
(data) pointer conversions require no actual computation, they only
change the type of the value. On the rare machines where say an int
pointer is different, and you want to do an int access, then the
runtime conversion is needed and had better be done.

0 new messages