Will somebody help assist me about the pointer issue?

S

sxzong

I have written a C program under unix, but some weird errors occurred:

====================================================
#include <stdio.h>

typedef unsigned long ULONG;
typedef unsigned short UWORD;
typedef unsigned char UBYTE;
typedef unsigned char BOOLEAN;

typedef struct
{
UBYTE i1;
UBYTE i2;
UWORD i3;
ULONG i4;

}TEST;

int main(void)
{
UBYTE temp[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};

UBYTE *temp1 = temp + 2;

UWORD *temp2 = (UWORD*)temp1;

UWORD * temp3 = (UWORD*)(temp+2);

ULONG * temp4 = (ULONG*)(temp+2);

TEST *temp5 = (TEST*)(temp+2);


printf("temp2 value: %xh\n", temp2[0]); // 203h
printf("temp3 value: %xh\n", temp3[0]); // 203h
printf("temp4 value: %xh\n", temp4[0]); // Bus error
printf("temp5 i1 value: %xh\n", temp5->i1); // 2h
printf("temp5 i2 value: %xh\n", temp5->i2); // 3h
printf("temp5 i3 value: %xh\n", temp5->i3); // 405h
printf("temp5 i4 value: %xh\n", temp5->i4); // Bus error

return 0;

}
====================================================

Thanks,
Tim
 
M

mark_bluemel

I have written a C program under unix, but some weird errors occurred:

====================================================
#include <stdio.h>

typedef unsigned long ULONG;
typedef unsigned short UWORD;
typedef unsigned char UBYTE;
typedef unsigned char BOOLEAN;

typedef struct
{
UBYTE i1;
UBYTE i2;
UWORD i3;
ULONG i4;

}TEST;

int main(void)
{
UBYTE temp[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};

UBYTE *temp1 = temp + 2;

UWORD *temp2 = (UWORD*)temp1;

UWORD * temp3 = (UWORD*)(temp+2);

ULONG * temp4 = (ULONG*)(temp+2);

TEST *temp5 = (TEST*)(temp+2);

printf("temp2 value: %xh\n", temp2[0]); // 203h
printf("temp3 value: %xh\n", temp3[0]); // 203h
printf("temp4 value: %xh\n", temp4[0]); // Bus error
printf("temp5 i1 value: %xh\n", temp5->i1); // 2h
printf("temp5 i2 value: %xh\n", temp5->i2); // 3h
printf("temp5 i3 value: %xh\n", temp5->i3); // 405h
printf("temp5 i4 value: %xh\n", temp5->i4); // Bus error

Apart from lying to the printf command and trying to access data which
is not guaranteed to be appropriately aligned, I can't find any
errors...
 
S

santosh

I have written a C program under unix, but some weird errors occurred:

====================================================
#include <stdio.h>

typedef unsigned long ULONG;
typedef unsigned short UWORD;
typedef unsigned char UBYTE;
typedef unsigned char BOOLEAN;

typedef struct
{
UBYTE i1;
UBYTE i2;
UWORD i3;
ULONG i4;

}TEST;

int main(void)
{
UBYTE temp[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
UBYTE *temp1 = temp + 2;
UWORD *temp2 = (UWORD*)temp1;
UWORD * temp3 = (UWORD*)(temp+2);
ULONG * temp4 = (ULONG*)(temp+2);
TEST *temp5 = (TEST*)(temp+2);


printf("temp2 value: %xh\n", temp2[0]); // 203h
printf("temp3 value: %xh\n", temp3[0]); // 203h
printf("temp4 value: %xh\n", temp4[0]); // Bus error
printf("temp5 i1 value: %xh\n", temp5->i1); // 2h
printf("temp5 i2 value: %xh\n", temp5->i2); // 3h
printf("temp5 i3 value: %xh\n", temp5->i3); // 405h
printf("temp5 i4 value: %xh\n", temp5->i4); // Bus error

return 0;

}
====================================================

The Bus error is probably caused due to your non-aligned memory reads.
Also most of your printf format specifiers and their arguments don't
match. That's undefined behaviour.

Why do you need to do this type punning?
 
M

Mohan

I have written a C program under unix, but some weird errors occurred:

====================================================
#include <stdio.h>

typedef unsigned long ULONG;
typedef unsigned short UWORD;
typedef unsigned char UBYTE;
typedef unsigned char BOOLEAN;

typedef struct
{
UBYTE i1;
UBYTE i2;
UWORD i3;
ULONG i4;

}TEST;

int main(void)
{
UBYTE temp[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};

UBYTE *temp1 = temp + 2;

UWORD *temp2 = (UWORD*)temp1;

UWORD * temp3 = (UWORD*)(temp+2);

ULONG * temp4 = (ULONG*)(temp+2);
This is wrong.
Address value, (temp + 2) may not be aligned to (sizeof ULONG) bytes.
For example if
(sizeof ULONG) is 8 bytes and if (temp + 2) is not aligned to 8 bytes,
the hardware may not allow
to read 8 bytes from that address and hence the bus error while
reading from that address.
Try printing (temp + 2) and you can verify that it is not aligned to
sizeof ULONG bytes.
TEST *temp5 = (TEST*)(temp+2);

printf("temp2 value: %xh\n", temp2[0]); // 203h
printf("temp3 value: %xh\n", temp3[0]); // 203h
printf("temp4 value: %xh\n", temp4[0]); // Bus error
printf("temp5 i1 value: %xh\n", temp5->i1); // 2h
printf("temp5 i2 value: %xh\n", temp5->i2); // 3h
printf("temp5 i3 value: %xh\n", temp5->i3); // 405h
printf("temp5 i4 value: %xh\n", temp5->i4); // Bus error
same reason as mentioned above.

Mohan
 
M

Martin Ambuhl

I have written a C program under unix, but some weird errors occurred:

There are no "weird" errors.
The only storage you allocated was of an unsigned char array.
You attempted to use the addresses of this array, aligned for chars, as
a pointer to unsigned shorts and unsigned longs. There is no reason to
think that char alignment is compatible with shorts and longs.
You further assumed that, not only temp[0] but also temp[2] were
correctly aligned for shorts and longs. Even if temp[0] were correctly
aligned for shorts and longs (which is a leap of faith on your part),
there is no reason to imagine temp[2] to be so.

In short, the only "weird error" is that you thought this to be
reasonable code.

====================================================
#include <stdio.h>

typedef unsigned long ULONG;
typedef unsigned short UWORD;
typedef unsigned char UBYTE;
typedef unsigned char BOOLEAN;

typedef struct
{
UBYTE i1;
UBYTE i2;
UWORD i3;
ULONG i4;

}TEST;

int main(void)
{
UBYTE temp[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};

UBYTE *temp1 = temp + 2;

UWORD *temp2 = (UWORD*)temp1;

UWORD * temp3 = (UWORD*)(temp+2);

ULONG * temp4 = (ULONG*)(temp+2);

TEST *temp5 = (TEST*)(temp+2);


printf("temp2 value: %xh\n", temp2[0]); // 203h
printf("temp3 value: %xh\n", temp3[0]); // 203h
printf("temp4 value: %xh\n", temp4[0]); // Bus error
printf("temp5 i1 value: %xh\n", temp5->i1); // 2h
printf("temp5 i2 value: %xh\n", temp5->i2); // 3h
printf("temp5 i3 value: %xh\n", temp5->i3); // 405h
printf("temp5 i4 value: %xh\n", temp5->i4); // Bus error

return 0;

}
====================================================

Thanks,
Tim
 
K

Keith Thompson

I have written a C program under unix, but some weird errors occurred:

Really? *What* "weird errors"? You showed us your program, but you
didn't show us any error messages or output.

I tried your program myself. On some systems, it dies with a bus
error; on others, it executes without any apparent problems.
====================================================
#include <stdio.h>

typedef unsigned long ULONG;

What benefit does this typedef give you? Why not just declare thinks
as 'unsigned long'? (Note that "it saves typing" is not a good
reason; readability is far more important than ease of typing.
typedef unsigned short UWORD;
typedef unsigned char UBYTE;
typedef unsigned char BOOLEAN;

These typedefs aren't quite as bad, since they don't just repeat an
abbreviated version of the type name, but UWORD makes an unwarranted
assumption that the size of an unsigned short is one "word" (whatever
that means).

If I read a declaration that uses the name UWORD, I have to go back up
to the top of the program to see what UWORD means.

[snip]
 
K

Keith Thompson

Mohan said:
I have written a C program under unix, but some weird errors occurred:

====================================================
#include <stdio.h>

typedef unsigned long ULONG;
typedef unsigned short UWORD;
typedef unsigned char UBYTE;
typedef unsigned char BOOLEAN;

typedef struct
{
UBYTE i1;
UBYTE i2;
UWORD i3;
ULONG i4;

}TEST;

int main(void)
{
UBYTE temp[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};

UBYTE *temp1 = temp + 2;

UWORD *temp2 = (UWORD*)temp1;

UWORD * temp3 = (UWORD*)(temp+2);

ULONG * temp4 = (ULONG*)(temp+2);
This is wrong. Address value, (temp + 2) may not be aligned to
(sizeof ULONG) bytes. For example if (sizeof ULONG) is 8 bytes and
if (temp + 2) is not aligned to 8 bytes, the hardware may not allow
to read 8 bytes from that address and hence the bus error while
reading from that address. Try printing (temp + 2) and you can
verify that it is not aligned to sizeof ULONG bytes.

Yes, it's wrong, but you mis-state the reasons.

temp is an array of unsigned char. The entire array, not just its
individual elements, can be at an arbitrary misaligned address. Array
objects are often given stricter alignment than one byte, but it's not
guaranteed.

It's possible that, just by coincidence, temp+2 could be 8-byte
aligned.

The required alignment for any type is implementation-specific. The
only real requirement is that the size must be a multiple of the
required alignment (since arrays cannot have gaps between elements).

It's likely that *some* of the pointers in the OP's program will be
misaligned, but the language doesn't give us a clue about which ones.
And there are systems where all types have only a one-byte alignment
requirement, and the program will "work".

[snip]
 
K

Keith Thompson

Keith Thompson said:
Really? *What* "weird errors"? You showed us your program, but you
didn't show us any error messages or output.
[...]

Sorry, I didn't notice that you showed (a brief summary of) the output
as comments in the program:

printf("temp2 value: %xh\n", temp2[0]); // 203h
printf("temp3 value: %xh\n", temp3[0]); // 203h
printf("temp4 value: %xh\n", temp4[0]); // Bus error
printf("temp5 i1 value: %xh\n", temp5->i1); // 2h
printf("temp5 i2 value: %xh\n", temp5->i2); // 3h
printf("temp5 i3 value: %xh\n", temp5->i3); // 405h
printf("temp5 i4 value: %xh\n", temp5->i4); // Bus error

It's still better to show the exact output separately; it's easier to
see, and it gives us more confidence that you've shown us the actual
output.

And it's unlikely that you got two bus errors in the same program.
Apparently you modified the program and re-ran it. It would have been
good to mention that.
 

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,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top