473,378 Members | 1,330 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,378 software developers and data experts.

((node*)&head)->next

Given that next is the first field in struct node,
and head is a pointer to node,
does assigning ((node*)&head)->next safely assign head ?

Illustration (this code works on many platforms)
#include <stdlib.h>
#include <stdio.h>

/* node structure for linked list */
typedef struct node
{
struct node* next;
char payload;
} node;

int main(void)
{
node *head, *last, *temp;
int c;
/* build list from stdin */
last = (node*)&head;
while ((c = getchar())!=EOF)
{
if ((temp = malloc(sizeof(node)))==NULL)
return 1;
temp->payload = c;
last->next = temp;
last = temp;
}
last->next = NULL;
/* then output list */
temp = head;
while (temp!=NULL)
{
putchar(temp->payload);
temp = temp->next;
}
return 0;
}

--
François Grieu
Nov 14 '05 #1
3 2598
In article <fg**************************@individual.net>
Francois Grieu <fg****@francenet.fr> wrote:
Given that next is the first field in struct node,
and head is a pointer to node,
does assigning ((node*)&head)->next safely assign head ?

Illustration (this code works on many platforms)
I would be surprised to find a platform on which this does *not*
work:
#include <stdlib.h>
#include <stdio.h>

/* node structure for linked list */
typedef struct node
{
struct node* next;
char payload;
} node;

int main(void)
{
node *head, *last, *temp;
int c;
/* build list from stdin */
last = (node*)&head;
while ((c = getchar())!=EOF)
{
if ((temp = malloc(sizeof(node)))==NULL)
return 1;
temp->payload = c;
last->next = temp;
last = temp;
}
last->next = NULL;

[etc]

But there is no need to resort to such subterfuge. Simply use
pointers the way they are intended:

node *head, *temp;
node **npp = &head;

while ((c = getchar()) != EOF) {
temp = malloc(sizeof *temp);
if (temp == NULL)
return EXIT_FAILURE;
temp->payload = c;
*npp = temp;
npp = &temp->next;
}
*npp = NULL;

While the head is just a pointer (of type "struct node *", aka
"node *"), each node also contains a pointer of that same type.
If we point a separate pointer ("npp") at each pointer in turn, we
can set each pointed-to pointer with absolute 100% guaranteed
safety, even though the "head" pointer is *just* a pointer, and
the other pointers are elements of a larger collection.

Naturally, to point to "struct node *" objects, we need a pointer
of type "struct node **" (aka "node **").

Note that this code continues to work even if the "next" field is
moved elsewhere in the list structure -- while the original code,
with its cast, stops working.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #2
On Mon, 13 Dec 2004 08:53:27 +0100, Francois Grieu wrote:
Given that next is the first field in struct node,
and head is a pointer to node,
does assigning ((node*)&head)->next safely assign head ?
This isn't safe because the alignment of a node structure may be stricter
than the alignment of a pointer to node. Also you are creating a pointer
to node value which isn't null and doesn't point at a valid node object,
or 1 past the end of an array of nodes.
Illustration (this code works on many platforms)


Yes, it is likely to work on many platforms but as far as C is concerned
it invokes undefined behaviour.

Chris's solution is well defined hence better.

Lawrence

Nov 14 '05 #3
Chris Torek <no****@torek.net> wrote:
Simply use pointers the way they are intended

node *head, *temp;
node **npp = &head;

while ((c = getchar()) != EOF) {
temp = malloc(sizeof *temp);
if (temp == NULL)
return EXIT_FAILURE;
temp->payload = c;
*npp = temp;
npp = &temp->next;
}
*npp = NULL;


Yes, that's clean.

For reasons not apparent in the sample code that I posted,
I wanted to keep a pointer to the last node in the list,
and Chris's code does not do that. But now I realize
that a pointer to the "next" field in the last node in the
list will do just as well, if not better.

Thanks Chris. Also, thanks Lawrence for a concrete reason
why the original code could fail (beside plain non-conformance).

--
François Grieu
Nov 14 '05 #4

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

Similar topics

72
by: Mel | last post by:
Are we going backwards ? (please excuse my spelling...) In my opinion an absolute YES ! Take a look at what we are doing ! we create TAGS, things like <H1> etc. and although there are tools...
0
by: ooze | last post by:
typedef unsigned long PARAM; typedef PARAM SAP; typedef struct qnode { struct qnode *next; struct qnode *prev; } QNODE;
0
by: gunimpi | last post by:
http://www.vbforums.com/showthread.php?p=2745431#post2745431 ******************************************************** VB6 OR VBA & Webbrowser DOM Tiny $50 Mini Project Programmer help wanted...
16
by: drwyness | last post by:
Hello, Please help with the following problem it is causing me some headaches. The following javascript code is designed to fill in text boxes with numbers on an online game (tribalwars). It...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.