473,545 Members | 2,005 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Small C "Puzzle"

I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(si zeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?

Thanks,

Rob Gamble
Nov 14 '05 #1
28 2821
Robert Gamble <ro**********@h otmail.com> wrote:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(si zeof(int));
*p = 10;
return 0;
}
Why does it happen so?


Did you check to make sure p != NULL ? There may have been a malloc() failure
for whatever reason.

--
Kristofer Pettijohn
kr*******@cyber netik.net
Nov 14 '05 #2
Robert Gamble <ro**********@h otmail.com> writes:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(si zeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?


The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86) because int
and pointer types are both 32 bits. The phrase "happens to work"
means that the undefined behavior manifests itself as the program
doing what you expected it to do. (This is actually worse than what
happens on the IA-64, since it masks the error.)

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #3
Robert Gamble wrote:

I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have
not had any trouble with any of them except for the first one
which is reproduced below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(si zeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic,
but I don't really see anything wrong with the code (yes,
stdlib.h is missing, int main(void), and malloc casted, but I
don't think this has anything to do with the point of the
problem). Am I missing something here? I don't have access
to an IA-64 machine, anyone who does have any insight?


Yes it does. Remove the unnecessary cast, which has prevented
compiler warnings, and #include <stdlib.h>, and the problem should
go away.

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #4

"Robert Gamble" <ro**********@h otmail.com> wrote in message
news:pa******** *************** *****@hotmail.c om...
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(si zeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem).
Actually, it *is* the problem. Although 'malloc()'s return value
is cast above, it's already too late. Lacking a proper prototype,
'malloc()' will be assumed to return type 'int'. So the valid
pointer value has already been corrupted by the conversion to
type 'int'. Casting this 'int' back to type 'int*' won't bring
back the original pointer value.(*)
Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?

Thanks,


(*) On some platforms/implementations (e.g. Windows), such conversions
between 'int' and a pointer type are indeed well defined, but not by
the language.

I'm not familiar with the 'IA' machines, but apparently the puzzle
is referring to the fact that trying to convert a pointer to an
int and back to a pointer will *not* work correctly on those
platforms.

-Mike
Nov 14 '05 #5

"Keith Thompson" <ks***@mib.or g> wrote in message
news:ln******** ****@nuthaus.mi b.org...
Robert Gamble <ro**********@h otmail.com> writes:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(si zeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?


The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86)


Ah, so I guess I *do* know what an 'IA' machine is. :-)
(In my other post I said I did not.)

-Mike
Nov 14 '05 #6
On Fri, 27 Aug 2004 23:38:11 +0000, Keith Thompson wrote:
Robert Gamble <ro**********@h otmail.com> writes:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(si zeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?


The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86) because int
and pointer types are both 32 bits. The phrase "happens to work"
means that the undefined behavior manifests itself as the program
doing what you expected it to do. (This is actually worse than what
happens on the IA-64, since it masks the error.)


I really did not consider this an option due to the fact that all the
other examples on the site cast malloc and declare main the same way. I
did just check though and all of the other examples do include proper
header files. I was overlooking the obvious thinking that there was a
deeper issue at work.

Thanks for the detailed explanation. Another reason I dismissed this as
my original answer was that I was thinking that int was 64 bits on IA-64
which did not seem any different from what would be happening on a 32-bit
machine. I'd forgotten this was not the case with most enviornments until
I read your post (I don't program on 64-bit machines yet ;)

I didn't want to beleive this was the answer because it didn't seem as
clear-cut as the other puzzles, kind of obvious and anti-climactic, but
you have talked me into it ;)

Thanks,

Rob Gamble
Nov 14 '05 #7
On Fri, 27 Aug 2004 23:38:11 GMT, Keith Thompson <ks***@mib.or g> wrote
in comp.lang.c:
Robert Gamble <ro**********@h otmail.com> writes:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(si zeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?


The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value.


Doesn't make any difference what size int or pointers are. The code
has undefined behavior because it calls ANY function with a return
type other than int without a prototype in scope. Period. Size of
anything irrelevant.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #8
> > The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(si zeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant ...

The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86) because int
and pointer types are both 32 bits. The phrase "happens to work"
means that the undefined behavior manifests itself as the program
doing what you expected it to do. (This is actually worse than what
happens on the IA-64, since it masks the error.)


I am little confused about the explanation.
I think size of "int" is size of processor register length.
And malloc retuns 64 bit address and pointer is also 64 bit (whether
int * or char *) , then where actually the size giving problem.

And can i know how the code below behaves on both platforms,

int main()
{
char* p;
p = (char*)malloc(s izeof(char));
*p = 10;
return 0;
}
Nov 14 '05 #9

"Raju" <g_************ **@yahoo.co.in> wrote

I am little confused about the explanation.
I think size of "int" is size of processor register length.
And malloc retuns 64 bit address and pointer is also 64 bit (whether
int * or char *) , then where actually the size giving problem.

And can i know how the code below behaves on both platforms,

int main()
{
char* p;
p = (char*)malloc(s izeof(char));
*p = 10;
return 0;
}


int *s and char *s are almost always the same size. ints are typically the
size of data registers, which are commonly but not always the size of
address registers (and on many architectures a register has a dual use). So
in early versions of C it was in fact accepted to assign a pointer to an
int, which is why we have the current problem of prototypes being essential
to make things work correctly.

If an int and a pointer are both 64 bits, then the undefined behaviour of
calling malloc() without a protoype in scope should normally be the
behaviour the programmer expects. In this case it appears that int was 32
bits and pointers 64 bits, so the ujndefined beahviour instead manifested
itself as a crash.
However there could be problems even if ints and pointers are the same
width, for instance the act of loading an address into a data register could
trigger a crash. With undefined behaviour, you just don't know.
Nov 14 '05 #10

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

Similar topics

3
2819
by: Trevor Andrew | last post by:
Hi There, I have a small ASP.NET application under development. I am using VS.NET 2002 (2003 upgrade is on the way) with .NET Framework 1.1. It is hosted on a web hosting service in the US. I am experiencing the "Viewstate corrupted" error message on a particular page, when that page is left for a period of time and I return to it again,...
2
11727
by: kj | last post by:
Here's a puzzle I can't figure out. I visited the page http://validator.w3.org, and confirmed that it validates itself. Then I *saved* it to my docroot directory using my browser's save-as function, and then tried to submit this saved page for validation. Now it generates 17 errors, of the form: end tag for "link" omitted, but OMITTAG...
2
6850
NewYorker
by: NewYorker | last post by:
Write a switch statement that tests the value of the char variable response and performs the following actions: if response is y , the message Your request is being processed is printed if response is n , the message Thank you anyway for your consideration is printed if response is h , the message Sorry, no help is currently...
0
3966
by: jeoffh | last post by:
Background: I am trying to "merge" some attributes into an existing XML column in my MS SQL 2005 database. The general idea is that I have an XML column in a table and I would like to update/delete some values while leaving the other values alone. I am designing this database/table/column so maybe I could use attributes or elements/nodes, the...
2
4193
by: slinky | last post by:
I'm getting a error when I open my . aspx in my browser... line 34: da.Fill(ds, "Assets") Here's the error and my entire code for this .aspx.vb is below that ... I need some clues as to what is causing the error... Thanks!!! Server Error in '/' Application. ---------------------------------------------------------------------------­----- ...
0
7411
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7926
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
7773
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5987
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
4962
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3468
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3450
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1901
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1028
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.