473,326 Members | 2,173 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Pointers to structs - help!

Jim
Ok, I'm having 'fun' with pointers to structures.

I've got some code that looks something like this:

====================
typedef struct
{
unsigned long *clno, *lastHistoryRecord;
} aRecord;

....
....

void main()
{
....
....
theRecord aRecord;

theRecord.clno = (unsigned long*) malloc(sizeof(long));
theRecord.lastHistoryRecord = (unsigned long*) malloc(sizeof(long));

getArecord( infile, &theRecord, recordNumber );

printf( "%ld %ld\n", theRecord.clno, theRecord.lastHistoryRecord );
....
....
}
int getArecord( FILE *infile, aRecord *thisRecord, long recordNumber )
{
....
....
fread( &thisRecord->lastHistoryRecord, 1L, sizeof(long), infile );
fread( &thisRecord->clno, 1L, sizeof( long ) * 1, infile );
....
....
return result;
}

====================

(large chunks of code snipped for brevity)
Now, it _seems_ to do as I expect. Let's say that I run this and get:

1000 1234

as a result. If I change the printf line to say:

printf( "%ld %ld\n", theRecord.clno-1, theRecord.lastHistoryRecord );

then I get

996 1234. I would have expected 999. So I'm obviously doing something very,
very stupid somewhere[0]. Could someone enlighten me? FWIW I've also tried
--theRecord.clno and (theRecord.clno)-1 but they both do the same.

Many thanks. Sorry if this is a really, really obvious one..!

Jim
[0] apart from not checking the mallocs for errors
--
http://www.ursaMinorBeta.co.uk
BANTEER (n. archaic)
A lusty and raucous old ballad sung after a particularly spectacular araglin
(q.v.) has been pulled off.
Oct 17 '07 #1
3 1409
Jim wrote:
typedef struct
{
unsigned long *clno, *lastHistoryRecord;
} aRecord;
So structures of this type contain pointers to unsigned longs - why not
just longs?
theRecord aRecord;

theRecord.clno = (unsigned long*) malloc(sizeof(long));
theRecord.lastHistoryRecord = (unsigned long*) malloc(sizeof(long));
That makes some sense, though I'd rather you at least said
"malloc(sizeof(unsigned long))", and dropped the cast (not helpful).

The c.l.c preferred form would be :-

theRecord.clno = malloc(sizeof(*theRecord.clno));

etc...
fread( &thisRecord->lastHistoryRecord, 1L, sizeof(long), infile );
fread( &thisRecord->clno, 1L, sizeof( long ) * 1, infile );
Here you pass fread() the _addresses_ of the pointers to long. So the
data read from the file is put there. Either you need to change this
code to remove the & characters, or change the structure to contain un
printf( "%ld %ld\n", theRecord.clno, theRecord.lastHistoryRecord );
This passes printf() two pointers and tells it it has two longs - this
is clearly wrong.
1000 1234
But you get away with it.

as a result. If I change the printf line to say:

printf( "%ld %ld\n", theRecord.clno-1, theRecord.lastHistoryRecord );

then I get

996 1234.
theRecord.clno is a pointer to unsigned long. Subtracting 1 from it
moves it "back" (for some value of back) by sizeof(unsigned long). Again
you pass printf() two pointers but tell it that they are longs, again
you "get away" with it...

Your code would work acceptably simply by amending the structure to
contain unsigned longs, rather than pointers to them, and removing the
mallocs...
Oct 17 '07 #2
Jim
On 2007-10-17, Mark Bluemel <ma**********@pobox.comwrote:
>
theRecord.clno is a pointer to unsigned long. Subtracting 1 from it
moves it "back" (for some value of back) by sizeof(unsigned long). Again
you pass printf() two pointers but tell it that they are longs, again
you "get away" with it...
Barely, it would seem.
Your code would work acceptably simply by amending the structure to
contain unsigned longs, rather than pointers to them, and removing the
mallocs...
Done and it now works as expected. Many thanks, and I'll try to get this
into my head in future.

Jim
--
http://www.ursaMinorBeta.co.uk
BRADWORTHY (n.)
One who is skilled in the art of naming loaves.
Oct 17 '07 #3
On Wed, 17 Oct 2007 13:32:03 +0100, Jim <ji*@magrathea.plus.com>
wrote:
>Ok, I'm having 'fun' with pointers to structures.

I've got some code that looks something like this:

====================
typedef struct
{
unsigned long *clno, *lastHistoryRecord;
} aRecord;
This defines a **type** known as aRecord.
>
...
...

void main()
main returns int.
>{
...
...
theRecord aRecord;
This is a syntax error. There is no type known as theRecord. Perhaps
you would like to show us your real code. Use cut and paste. Do not
attempt to retype it.
>
theRecord.clno = (unsigned long*) malloc(sizeof(long));
Don't cast the return from malloc. The only thing it accomplishes is
preventing the compiler from issuing a diagnostic which you would
really want to see.

It is always desirable that the operand of sizeof match the type of
the object being pointed to. long and unsigned long may have the same
size but it is a better style. To this end, the frequent
recommendation here is
theRecord.clno = malloc(sizeof *theRecord.clno);
which will still be correct if you later need to change the type of
clno.
theRecord.lastHistoryRecord = (unsigned long*) malloc(sizeof(long));

getArecord( infile, &theRecord, recordNumber );

printf( "%ld %ld\n", theRecord.clno, theRecord.lastHistoryRecord );
This is undefined behavior. Neither the second nor third arguments
match the type of the respective format specification. Both are
pointers where the format requires a long.

If you meant to print the pointer values (unlikely), use %p and cast
the arguments to void*. If you meant to print the values pointed to,
then apply the dereference operator (*) to both arguments.
>...
...
}
int getArecord( FILE *infile, aRecord *thisRecord, long recordNumber )
You did know the correct type name.
>{
...
...
fread( &thisRecord->lastHistoryRecord, 1L, sizeof(long), infile );
This will work only if the data in infile was produced on a system
which stores long values EXACTLY the same as the system you are
running this program on.
fread( &thisRecord->clno, 1L, sizeof( long ) * 1, infile );
...
...
return result;
}

====================

(large chunks of code snipped for brevity)
Now, it _seems_ to do as I expect. Let's say that I run this and get:

1000 1234
By very bad luck, the undefined behavior printed pointer values that
very much resemble integers.
>
as a result. If I change the printf line to say:

printf( "%ld %ld\n", theRecord.clno-1, theRecord.lastHistoryRecord );

then I get

996 1234. I would have expected 999. So I'm obviously doing something very,
By equally bad luck, sizeof(long) on your system is 4 and the pointer
arithmetic resulted in another value that looks like an integer.
>very stupid somewhere[0]. Could someone enlighten me? FWIW I've also tried
--theRecord.clno and (theRecord.clno)-1 but they both do the same.

Many thanks. Sorry if this is a really, really obvious one..!
You want *theRecord.clno-1. This dereferences the pointer to obtain
the long value and subtracts one from that value, not from the
pointer.
>
Jim
[0] apart from not checking the mallocs for errors

Remove del for email
Oct 19 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

388
by: maniac | last post by:
Hey guys, I'm new here, just a simple question. I'm learning to Program in C, and I was recommended a book called, "Mastering C Pointers", just asking if any of you have read it, and if it's...
3
by: Christian F | last post by:
Hi, I'm a C-newbie and I would like to know if I am doing something wrong in the code below. It is working, but I'm afraid it might not be correct because I don't really understand everything of...
8
by: John Hanley | last post by:
I working in C. I haven't paid much attention to void pointers in the past, but I am wondering if I can use them for my various linked lists to save work. I have two different linked lists that...
47
by: sunglo | last post by:
Some time a go, in a discussion here in comp.lang.c, I learnt that it's better not to use a (sometype **) where a (void **) is expected (using a cast). Part of the discussion boiled down to the...
5
by: Paminu | last post by:
Why make an array of pointers to structs, when it is possible to just make an array of structs? I have this struct: struct test { int a; int b;
2
by: Peter Steele | last post by:
Say I have a managed C++ app with some code that looks something like this: void MyMethod() { struct Point { int x, y; }; Point* p = new Point; p.x = 1; p.y = 2;
17
by: Johan Tibell | last post by:
Could someone outline the pros and cons of typedefing pointers to structs like this? typedef struct exp_ { int val; struct exp_ *child; } *exp; (This is straight from memory so it might not...
64
by: Zytan | last post by:
I know there are no pointers in C#, but if you do: a = b; and a and b are both arrays, they now both point to the same memory (changing one changes the other). So, it makes them seem like...
5
by: dev_15 | last post by:
Hi, I'm going through some code and thought that this allocates an array of structs but its supposed according to comments to allocate an array of pointer to structs. What does it actually do ...
2
by: hal | last post by:
Hi, I'm trying to make an array of pointers to 'TwoCounts' structs, where the size of the array is arraySize. Right now I'm just mallocing enough space for all the pointers to the structs, and...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.