473,326 Members | 2,168 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.

Pointer Question

Hi all,

I have the following question regd pointer typecasting. Is the
following type of pointer typecasting valid?
#define ALLOC(type,num) ((type *)malloc(sizeof(type)*num))

/*begin code*/

struct node{
:
} node;

typedef node *nodeptr;
node **nodeptrptr;

nodeptrptr = (nodeptr *)ALLOC(node,NUM_OF_NODES)

/*end code*/

Is the above code valid? If so, can anyone explain how it works? How
can a pointer to a memory chunk be typecast to a pointer to a pointer
to a memchunk?

Thanks,
Arun
Nov 13 '05 #1
9 3459
ar************@yahoo.com (Arun Prasath) wrote in message news:<a3**************************@posting.google. com>...
Hi all,

I have the following question regd pointer typecasting. Is the
following type of pointer typecasting valid?
#define ALLOC(type,num) ((type *)malloc(sizeof(type)*num))

/*begin code*/

struct node{
:
} node;

typedef node *nodeptr;
node **nodeptrptr;

nodeptrptr = (nodeptr *)ALLOC(node,NUM_OF_NODES)

/*end code*/

Is the above code valid? If so, can anyone explain how it works? How
can a pointer to a memory chunk be typecast to a pointer to a pointer
to a memchunk?
You can get this code to compile. But it is not going to work. How are
you planning to use this nodeptrptr?

The typecast would convert this pointer into a pointer to a pointer
type, but how would you dereference this? First dereference would give
you the value stored at the location which was allocated using
ALLOC.The second dereference would treat this data as an address and
try to get the value at this address which wouldn't be valid.If your
application is going to ensure that this value is going to be a valid
address, then this would work but looks like a very dangerous way of
doing this.
Thanks,
Arun

Nov 13 '05 #2


Arun Prasath wrote:
Hi all,

I have the following question regd pointer typecasting. Is the
following type of pointer typecasting valid?
It will not compile as written.

#define ALLOC(type,num) ((type *)malloc(sizeof(type)*num))

/*begin code*/

struct node{
:
} node;
You will need to make a vaiid struct.
typedef node *nodeptr;
typedef struct node nodeptr; node **nodeptrptr;
struct node **nodeptrptr;

nodeptrptr = (nodeptr *)ALLOC(node,NUM_OF_NODES)

nodeprtptr is type node **. There is a mismatch.
I believe you want something like:

nodeptr p = ALLOC(struct node,NUM_OF_NODES)
/*end code*/

Is the above code valid? If so, can anyone explain how it works? How
can a pointer to a memory chunk be typecast to a pointer to a pointer
to a memchunk?


You want to use a struct pointer to a struct pointer like this?

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define NUM_OF_NODES 3
#define ALLOC(type,num) malloc(sizeof(type)*num)

struct node{
char name[32];
};

typedef struct node *nodeptr;

int main(void)
{
nodeptr p = ALLOC(struct node,NUM_OF_NODES);
struct node **nodeptrptr = ALLOC(*nodeptrptr,NUM_OF_NODES);
unsigned i;

if(!p || !nodeptrptr) exit(EXIT_FAILURE);
for(i = 0;i < NUM_OF_NODES;i++)
{
sprintf(p[i].name,"%u. Hello",i+1);
nodeptrptr[i] = &p[i];
printf("p[%u].name = \"%s\"\n",i,p[i].name);
printf("nodeptrptr[%u]->name = \"%s\"\n\n",i,nodeptrptr[i]->name);
}
free(p);
free(nodeptrptr);
return 0;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 13 '05 #3
On 23 Nov 2003 19:59:18 -0800, ar************@yahoo.com (Arun Prasath)
wrote:
Hi all,

I have the following question regd pointer typecasting. Is the
following type of pointer typecasting valid?
#define ALLOC(type,num) ((type *)malloc(sizeof(type)*num))
The cast on malloc's return is unnecessary and ill advised. It can
never help but it can cause the compiler to suppress a diagnostic you
really want to see.
/*begin code*/

struct node{
:
} node;

typedef node *nodeptr;
node **nodeptrptr;

nodeptrptr = (nodeptr *)ALLOC(node,NUM_OF_NODES)
This is an excellent example of why you don't want to do this. You
are allocating enough space for a quantity of structures. However,
The pointer which will receive the address cannot point to a
structure. It must point to a pointer to structure. If the size of
the structure is smaller than the size of a pointer (unlikely but
possible), it will not allocate enough space for all the pointers you
want. More than likely, it will allocate way more space that you
need.

The oft repeated recommendation for malloc is
some_pointer = malloc(quantity * sizeof *some_pointer);
which will always allocate the correct amount of space for the
quantity of objects the pointer points to (or return NULL).

/*end code*/

Is the above code valid? If so, can anyone explain how it works? How
can a pointer to a memory chunk be typecast to a pointer to a pointer
to a memchunk?

If T is a typedef for an object type that occupies some quantity of
memory, then T* is the type for pointer to T and T** is the type for
pointer to pointer to T. You definition of nodeptrptr works fine.
<<Remove the del for email>>
Nov 13 '05 #4
Groovy hepcat Arun Prasath was jivin' on 23 Nov 2003 19:59:18 -0800 in
comp.lang.c.
Pointer Question's a cool scene! Dig it!
I have the following question regd pointer typecasting. Is the
following type of pointer typecasting valid?

#define ALLOC(type,num) ((type *)malloc(sizeof(type)*num))
No. Casting the return value of malloc() is never valid. It is
legal, but never useful, and can actually hide a serious bug.
Kindly read the newsgroup for the usual month or two and read the
FAQ before posting again. Had you done so, you would not have needed
to ask.
/*begin code*/

struct node{
:
} node;
This creates an object named node. It does not create a type named
node. It creates a type named struct node, however.
typedef node *nodeptr;
And since there is no type named node, this declaration is invalid.
node **nodeptrptr;
So is this one.
nodeptrptr = (nodeptr *)ALLOC(node,NUM_OF_NODES)

/*end code*/

Is the above code valid? If so, can anyone explain how it works? How
Nope. Noone can explain how it works, because it may not work (and
that's even if you fix the broken declarations). And if it does, then
it does so merely by accident. Calling malloc() without a valid
declaration (provided by including stdlib.h, which you neglected to do
here) causes undefined behaviour.
can a pointer to a memory chunk be typecast to a pointer to a pointer
to a memchunk?


No. Well, semantically it can. But logically it is incorrect and
useless to do so.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Nov 13 '05 #5
Peter Shaggy Haywood wrote:

Groovy hepcat Arun Prasath was jivin' on 23 Nov 2003 19:59:18 -0800 in
comp.lang.c.
can a pointer to a memory chunk be typecast to a pointer to a pointer
to a memchunk?


No. Well, semantically it can. But logically it is incorrect and
useless to do so.


Actually, it seems like a perfectly valid way to handle a
linked list, or any linked data structure. The usual formulation
looks like

struct chunk {
struct chunk *next;
char payload[42];
} *p;
p = malloc(sizeof *p); // assume success
p->next = malloc(sizeof *p->next); // assume success
p->next->next = NULL;

However, the final line could also have been written as

*(struct next**)p = NULL;

.... showing that "a pointer to a memory chunk [can] be typecast
to a pointer to a pointer to a memchunk" and be useful.

Now, why would anyone use the obfuscated rewrite instead
of the crystal-clear original? It would be foolish not to take
advantage of the mnemonic value of the `next' identifier -- but
to do so, the `struct chunk' declaration must be in scope. What
if you're writing a library function that deals in "opaque"
struct types, whose declarations are not available?

For example, my little bag of tricks includes a function to
merge-sort linked lists of structs of arbitrary type. The
function definition begins

void *listsort(void *head, size_t offset,
int (*compare)(const void *, const void *))

.... where `head' points to the first struct of the original list,
`offset' is the byte offset of the forward link in each struct,
and `compare' is the usual comparison function a la qsort().
How does this function navigate the list's links, and how does
it modify them to reflect the result of the sort? By exactly
the kind of casting described above:

void *next = *((struct x**)((char*)head + offset);

Of course, I wrap this up in some macros to save my sanity,
but that's just syntactic sugar. The cast is still there:
`(char*)head + offset' is a "pointer to a memory chunk," this
is then "typecast to a pointer to a pointer to a memchunk"
(of incomplete type, no less), and the result turns out to be
not only useful, but essential.

--
Er*********@sun.com
Nov 13 '05 #6
Eric Sosman wrote:
.... snip ...
p->next->next = NULL;

However, the final line could also have been written as

*(struct next**)p = NULL;

... showing that "a pointer to a memory chunk [can] be typecast
to a pointer to a pointer to a memchunk" and be useful.

Now, why would anyone use the obfuscated rewrite instead
of the crystal-clear original? It would be foolish not to take
advantage of the mnemonic value of the `next' identifier -- but
to do so, the `struct chunk' declaration must be in scope. What
if you're writing a library function that deals in "opaque"
struct types, whose declarations are not available?

For example, my little bag of tricks includes a function to
merge-sort linked lists of structs of arbitrary type. The
function definition begins

void *listsort(void *head, size_t offset,
int (*compare)(const void *, const void *))

... where `head' points to the first struct of the original list,
`offset' is the byte offset of the forward link in each struct,
and `compare' is the usual comparison function a la qsort().
How does this function navigate the list's links, and how does
it modify them to reflect the result of the sort? By exactly
the kind of casting described above:

void *next = *((struct x**)((char*)head + offset);


My attitude would be to simply insist that the next field be the
first field in the structure, ensuring offset of 0, and avoiding
many gyrations. Of course the code is not as general as yours,
but does that really matter?

In point of fact I like to build lispish car/cdr structures, with
the cdr pointing to the data. struct node {struct node *next;
void *datum};

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #7
[Posted and mailed]

In message <3f**************@news.australis.net>
sh****@australis.net.STOP.SPAM (Peter "Shaggy" Haywood) wrote:
Groovy hepcat Arun Prasath was jivin' on 23 Nov 2003 19:59:18 -0800 in
comp.lang.c.
Pointer Question's a cool scene! Dig it!
I have the following question regd pointer typecasting. Is the
following type of pointer typecasting valid?

#define ALLOC(type,num) ((type *)malloc(sizeof(type)*num))


No. Casting the return value of malloc() is never valid. It is
legal, but never useful, and can actually hide a serious bug.


Yawn, reflex rude response without engaging brain. If that macro is defined
in a header file that #includes <stdlib.h>, your serious bug can't occur. And
the cast inside the macro will guarantee type-safety when the macro is used.
I don't see any real problem with it at all in this instance.

The macro produces something functionally equivalent to

thing *make_array_of_things(size_t n)
{
return malloc(n * sizeof(thing));
}

and surely it's better that that returns a thing * than a void *.

We don't know whether or not the OP intended to include <stdlib.h> because
he didn't post a full program. I don't see any reason to leap to flame him.
Except that this is comp.lang.c, and it's force of habit.

I'd recommend putting brackets around the num in the replacement though.

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1223 503458
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 13 '05 #8
Groovy hepcat Kevin Bracey was jivin' on Thu, 27 Nov 2003 12:08:47 GMT
in comp.lang.c.
Re: Pointer Question's a cool scene! Dig it!
[Posted and mailed]

In message <3f**************@news.australis.net>
sh****@australis.net.STOP.SPAM (Peter "Shaggy" Haywood) wrote:
Groovy hepcat Arun Prasath was jivin' on 23 Nov 2003 19:59:18 -0800 in
comp.lang.c.
Pointer Question's a cool scene! Dig it!
>I have the following question regd pointer typecasting. Is the
>following type of pointer typecasting valid?
>
>#define ALLOC(type,num) ((type *)malloc(sizeof(type)*num))
No. Casting the return value of malloc() is never valid. It is
legal, but never useful, and can actually hide a serious bug.


Yawn, reflex rude response without engaging brain. If that macro is defined
in a header file that #includes <stdlib.h>, your serious bug can't occur. And


And where is it indicated that the OP had this in a header that also
included stdlib.h? He asked a fairly general question about a
construct, and I gave him a fairly general answer. Had he indicated
that he was including stdlib.h I wouldn't have mentioned it.
the cast inside the macro will guarantee type-safety when the macro is used.
I don't see any real problem with it at all in this instance.

The macro produces something functionally equivalent to

thing *make_array_of_things(size_t n)
{
return malloc(n * sizeof(thing));
}

and surely it's better that that returns a thing * than a void *.

We don't know whether or not the OP intended to include <stdlib.h> because
he didn't post a full program. I don't see any reason to leap to flame him.
I didn't flame him. Why are you so sensitive? I merely pointed out a
problem with the code. It was intended to help. What's your problem?
Except that this is comp.lang.c, and it's force of habit.

I'd recommend putting brackets around the num in the replacement though.


Me too.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Nov 13 '05 #9
CBFalconer wrote:

Eric Sosman wrote:

For example, my little bag of tricks includes a function to
merge-sort linked lists of structs of arbitrary type. [...]
How does this function navigate the list's links [...]?

void *next = *((struct x**)((char*)head + offset);


My attitude would be to simply insist that the next field be the
first field in the structure, ensuring offset of 0, and avoiding
many gyrations. Of course the code is not as general as yours,
but does that really matter?


Design preferences, I guess. Insisting on a zero offset
saves you an addition, and can also eliminate a cast (at the
cost, I guess, of a dummy struct declaration somewhere). On
the other hand, coping with the offset explicitly makes it
easy to manage multilinked structures:

typedef struct node_s {
double coefficient;
int row, col;
struct node_s *nextr, *nextc;
} SparseMatrixNode;

.... and I can sort the `nextr' and `nextc' chains independently.
On the gripping hand, though, I confess it's pretty rare that
I find myself actually using this capability.

--
Er*********@sun.com
Nov 13 '05 #10

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

Similar topics

37
by: Ben | last post by:
Hi, there. Recently I was working on a problem where we want to save generic closures in a data structure (a vector). The closure should work for any data type and any method with pre-defined...
20
by: __PPS__ | last post by:
Hello everybody in a quiz I had a question about dangling pointer: "What a dangling pointer is and the danger of using it" My answer was: "dangling pointer is a pointer that points to some...
4
by: anonymous | last post by:
Thanks your reply. The article I read is from www.hakin9.org/en/attachments/stackoverflow_en.pdf. And you're right. I don't know it very clearly. And that's why I want to understand it; for it's...
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
17
by: Christian Wittrock | last post by:
Hi, What does ANSI C say about casting an 8 bit pointer to a 16 bit one, when the byte pointer is pointing to an odd address? I have detected a problem in the Samsung CalmShine 16 compiler. This...
26
by: Bill Reid | last post by:
Bear with me, as I am not a "professional" programmer, but I was working on part of program that reads parts of four text files into a buffer which I re-allocate the size as I read each file. I...
9
by: Cyron | last post by:
Hello friends, Recently I have begun exploring the features that the STL map collection provides. While learning how it worked, I encountered a result that confused me. Up until now, I had...
5
by: mdh | last post by:
Hi all, I have gone through the FAQ and done searches in the Comp.Lang and if I have missed it please let me have the ref. (Question generated in part by p119). Given char a;
9
by: subramanian100in | last post by:
The following portion is from c-faq.com - comp.lang.c FAQ list · Question 6.13 int a1 = {0, 1, 2}; int a2 = {{3, 4, 5}, {6, 7, 8}}; int *ip; /* pointer to int */ int (*ap); /* pointer to...
2
by: Giorgos Keramidas | last post by:
On Sun, 05 Oct 2008 18:22:13 +0300, Giorgos Keramidas <keramida@ceid.upatras.grwrote: My apologies. I should have been less hasty to hit `post'. If showtext() is passed a null pointer, it may...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
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: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
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...

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.