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

Help. What is the error?

The following C program segfaults on 64 bit Arch., but works fine on 32
bit.

int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}

Why does it happen so?

Nov 15 '05 #1
13 1481
remove the 'cast' to malloc and
#include <stlib.h>

will work fine on all platforms

- Ravi

param wrote:
The following C program segfaults on 64 bit Arch., but works fine on 32
bit.

int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}

Why does it happen so?


Nov 15 '05 #2
param wrote:
The following C program segfaults on 64 bit Arch., but works fine on 32
bit.

int main() it should really be int main(void)
{
int* p;
p = (int*)malloc(sizeof(int)); As Ravi noted, remove the cast. And make sure you have included stdlib.h.
Also, check if malloc has succeeded before using it.
*p = 10;
return 0;
}

Why does it happen so?

--
"If you would be a real seeker after truth, it is necessary that at
least once in your life you doubt, as far as possible, all things."
-- Rene Descartes
Nov 15 '05 #3
param wrote:
The following C program segfaults on 64 bit Arch., but works fine on 32
bit.

int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}

Why does it happen so?


This will crash because:

1) You did not include the proper header to malloc.
2) The compiler assumes it is an unknown function that returns
the default result: an integer.
3) The compiler generates code to read an integer result from malloc
(32 bit integer) and then casts it to a 64 bit pointer. Some
bits of the pointer are lost.
4) Since you did a cast to (int *) the compiler will not warn you
about casting an integer to a pointer since it is explicitely
asked for.
5) You store the wrong address in the pointer and when you use it it
crashes.

jacob
Nov 15 '05 #4
Vimal Aravindashan wrote:
param wrote:
The following C program segfaults on 64 bit Arch., but works fine on 32
bit.

int main()


it should really be int main(void)
{
int* p;
p = (int*)malloc(sizeof(int));


As Ravi noted, remove the cast. And make sure you have included stdlib.h.
Also, check if malloc has succeeded before using it.


In addition, without the cast the compiler was *required* to complain at
you because int and pointers are not assignment compatible. If param put
in the cast to shut the compiler up then it just goes to show *why* you
should never put in a cast to shut the compiler up, you only put in
casts (or make any other change) when you understand *why* the compiler
complained and exactly what the effect will be.

The generally preferred form for calling malloc around here is
p = malloc(N * sizeof *p);
where N is the number of items you want space for. So when, as in this
case, you want space for one item you can simplify it to
p = malloc(sizeof *p);
Far less typing, the compiler is *required* to complain if you forget to
include stdlib.h (unless you have done something else really stupid) and
easier to maintain since it does not need changing if you have to change
p from int* to long* or anything else.
*p = 10;
return 0;
}

Why does it happen so?


All the advice from Ravi and Vimal was correct, although they have not
explained why, so I'll add that information.

The ANSI standard for C that was release in 1989 specified that if the
compiler has not seen a declaration for a function (or if it saw a
declaration that did not specify a return type) that it should assume
that the function returned an int. It also specified that it was
undefined behaviour (i.e. *anything* can happen) if this assumption was
made but the function actually returned something else.

On your 32 bit platform int and void* are both 32 bits and the same
method is being used to return either type so it just happens to do what
you expect.

On your 64 bit platform you probably have int as 32 bits and void* as 64
bits. So malloc returns a 64 bit pointer, but when main was compiled the
compiler assumed it would be getting a 32 bit int, so it only grabs half
of the address and then converts that in to a pointer which obviously
produces a garbage value. E.g. malloc returns a pointer with the bit
pattern of 0x1122334455667788 but main only "sees" 0x11223344 and
converts that to address 0x0000000011223344 which you are not allowed to
access.

It can also fail for other reasons on platforms where int and void* are
the same size, for example if addresses are returned in an address
register and integers in a data register, which does happen on some systems.

The morals of the story are *always* include the correct headers to
provide prototypes for the functions you will be using otherwise
anything might happen and don't go adding casts just to shut the
compiler up.

PS, Ravi, please put your reply *under* the text you are replying to not
above. It makes it *far* easier for people to follow the thread and is
generally considered here (and in a lot of other places) to be the
polite way to post.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #5
param wrote:

The following C program segfaults on 64 bit Arch., but works fine on 32
bit.

int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}

Why does it happen so?


Another perfect example of "don't cast the return from malloc".

You have hidden the fatal error (can't implicitly convert from "int" to
"int*") with a non-fatal warning (the explicit cast).

You need to include <stdlib.h> to get malloc's prototype.

Why does it fail on one system and work on another? Because that's how
"undocumented behavior" behaves.

As for specifics, my guess is that sizeof(int)==sizeof(void*) on the 32-bit
platform, and sizeof(int)!=sizeof(void*) on the 64-bit one.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Nov 15 '05 #6
Flash Gordon wrote:
The generally preferred form for calling malloc around here is
p = malloc(N * sizeof *p);


I'd rather write

p = malloc(N * sizeof(*p));

Yes, the parentheses are redundant. But scanning "N * sizeof *p" always
makes me think of "N * sizeof * p", which isn't good.

Of course, diff'rent strokes, and there's not much ground to gain on the
microscopic level, but still.

S.
Nov 15 '05 #7
In article <43***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.net> wrote:
Another perfect example of "don't cast the return from malloc".


Too perfect if you ask me! Is this some kind of reverse troll?

-- Richard
Nov 15 '05 #8
Kenneth Brody wrote:
param wrote:
The following C program segfaults on 64 bit Arch., but works fine on 32
bit.

int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}

Why does it happen so?
Another perfect example of "don't cast the return from malloc".

You have hidden the fatal error (can't implicitly convert from "int" to
"int*") with a non-fatal warning (the explicit cast).


The standard does not say the diagnostic has to be fatal without the
cast. With the cast no diagnostic is required for the conversion (and
not all compilers will give you a warning), although under C99 I think a
diagnostic is required due to the lack of a declaration the the removal
of implicit int from the language.
You need to include <stdlib.h> to get malloc's prototype.

Why does it fail on one system and work on another? Because that's how
"undocumented behavior" behaves.
You mean "undefined behaviour" not "undocumented behaviour".
As for specifics, my guess is that sizeof(int)==sizeof(void*) on the 32-bit
platform, and sizeof(int)!=sizeof(void*) on the 64-bit one.


Indeed. Although for it to "work" requires more than just the sizes
matching, it also requires the same return mechanism for pointers and
integers.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #9
Kenneth Brody wrote:
You need to include <stdlib.h> to get malloc's prototype.

Why does it fail on one system and work on another? Because that's how
"undocumented behavior" behaves.


The code will work if the returned pointer lies in the first 4GB
virtual memory space, it will crash if it doesn't.
Nov 15 '05 #10
jacob navia <ja***@jacob.remcomp.fr> writes:
Kenneth Brody wrote:
You need to include <stdlib.h> to get malloc's prototype.
Why does it fail on one system and work on another? Because that's
how "undocumented behavior" behaves.

As others have pointed out, this is probably a typo for "undefined
behavior".
The code will work if the returned pointer lies in the first 4GB
virtual memory space, it will crash if it doesn't.


Not necessarily. It could work on a 64-bit system if 32-bit and
64-bit types happen to be passed as arguments in the same way, or if
int, void*, and int* are all 64 bits. It could either succeed or fail
on a 64-bit system with a pointer in the first 4GB of the virtual
memory space depending on whether the system is big-endian or
little-endian. It could fail on either a 32-bit or a 64-bit system if
integer and pointer arguments are passed by different mechanisms, for
example in different registers. It could misbehave without actually
crashing on a 64-bit system if the truncated pointer value happens to
be a valid and accessible address. And so on.

The OP asked about 32-bit and 64-bit systems. He gave no clue about
which systems he was using, and it's unwise and unnecessary to assume
he meant, say, x86-32 and x86-64.

Undefined behavior is undefined behavior. It can certainly be useful
to discuss what the likely consequences are, particularly in
debugging, but all such discussions are system-specific and can only
be in terms of likelihoods unless you go down to a level of detail
that's inappropriate for this newsgroup.

You cannot correctly claim that the code "will work" in some
circumstances or "will creash" in other circumstances.

--
Keith Thompson (The_Other_Keith) 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 15 '05 #11
jacob navia wrote:

Kenneth Brody wrote:
You need to include <stdlib.h> to get malloc's prototype.

Why does it fail on one system and work on another? Because that's how
"undocumented behavior" behaves.

(Yes, that was a typo for "undefined behavior".)
The code will work if the returned pointer lies in the first 4GB
virtual memory space, it will crash if it doesn't.


Not necessarily. I have seen platforms where the return value from a
function will be in one register for pointers, and a diferent register
for non-pointers. If you haven't properly declared the function as
returning a pointer, then the return value you look at has nothing to
do with the actual return value.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Nov 15 '05 #12
Keith Thompson wrote:

The OP asked about 32-bit and 64-bit systems. He gave no clue about
which systems he was using, and it's unwise and unnecessary to assume
he meant, say, x86-32 and x86-64.


You are right. It can fail in many other ways.

jacob
Nov 15 '05 #13

In article <43***************@spamcop.net>, Kenneth Brody <ke******@spamcop.net> writes:
jacob navia wrote:
The code will work if the returned pointer lies in the first 4GB
virtual memory space, it will crash if it doesn't.


Not necessarily. I have seen platforms where the return value from a
function will be in one register for pointers, and a diferent register
for non-pointers. If you haven't properly declared the function as
returning a pointer, then the return value you look at has nothing to
do with the actual return value.


The ever-lovin' AS/400 (EPM C/400, to be precise, though this should
apply to all the AS/400 C implementations) was one where malloc
without a prototype never "worked". There, int is 32 bits and void*
is 128 bits; and more importantly, the implementation validates every
pointer at runtime. You can coerce an integer value into a pointer
type with a cast, but try to do anything with it and you get a
friendly machine check in your job.

Of course, all this just boils down to "not everything is a PC".

--
Michael Wojcik mi************@microfocus.com

An intense imaginative activity accompanied by a psychological and moral
passivity is bound eventually to result in a curbing of the growth to
maturity and in consequent artistic repetitiveness and stultification.
-- D. S. Savage
Nov 15 '05 #14

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

Similar topics

6
by: wukexin | last post by:
Help me, good men. I find mang books that introduce bit "mang header files",they talk too bit,in fact it is my too fool, I don't learn it, I have do a test program, but I have no correct doing...
5
by: xuatla | last post by:
Hi, I encountered the following compile error of c++ and hope to get your help. test2.cpp: In member function `CTest CTest::operator+=(CTest&)': test2.cpp:79: error: no match for 'operator='...
9
by: YZK | last post by:
Hello. I'm not a Web developer, just a user, and I think I may have somehow messed myself up majorly. I'm not quite sure how. Right now, javascript used by websites I go to either does not work at...
8
by: baustin75 | last post by:
Posted: Mon Oct 03, 2005 1:41 pm Post subject: cannot mail() in ie only when debugging in php designer 2005 -------------------------------------------------------------------------------- ...
1
by: Dave | last post by:
I am having problems accessing DTS after install SP4 and was wondering if someone could offer some advice. I installed SP4 and got the following error after it competed. Unable to write to...
6
by: Jax | last post by:
I have Visual Studio 2002 Standard Edition. It has been working fine up to a point and now i'm at that point. Due to the limitations of the edition i am not using any of my own .dll's and instead...
5
by: Marc Violette | last post by:
<Reply-To: veejunk@sympatico.ca> Hello, I'm hoping someone can help me out here... I'm a beginner ASP.NET developper, and am trying to follow a series of exercises in the book entitled...
6
by: James Radke | last post by:
Hello, I have a multithreaded windows NT service application (vb.net 2003) that I am working on (my first one), which reads a message queue and creates multiple threads to perform the processing...
1
by: Rahul | last post by:
Hi Everybody I have some problem in my script. please help me. This is script file. I have one *.inq file. I want run this script in XML files. But this script errors shows . If u want i am...
12
by: =?Utf-8?B?ZGdvdw==?= | last post by:
I designed a "contact_us" page in visual web developer 2005 express along with EW2 after viewing tutorials on asp.net's help page. Features work like they should, but I cannot figure out how to...
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: 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?
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...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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...

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.