why it doesn't work?

Discussion in 'C Programming' started by junky_fellow@yahoo.co.in, Feb 15, 2010.

  1. Guest

    Guys,

    Consider the following two files, files test.c and test1.c

    Contents of test1.c are as follows:
    ---------------------------------------------------

    int arr[] = { 0x100, 0x200 };
    int main(void)
    {
    printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
    func();
    }

    Contents of test1.c
    ------------------------------
    extern int *arr;

    func()
    {
    printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
    }

    The 2 files are compiled without any error, but when I run the
    executable generated, it crashes with segmentation fault.

    Can someone please explain what is the reason for crash ?
    , Feb 15, 2010
    #1
    1. Advertising

  2. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    wrote:

    > ---------------------------------------------------
    >
    > int arr[] = { 0x100, 0x200 };
    > int main(void)
    > {
    > printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
    > func();
    > }
    >
    > Contents of test1.c
    > ------------------------------
    > extern int *arr;
    >
    > func()
    > {
    > printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
    > }
    >

    Short:
    A pointer object is not an array object, they aren't layout-compatible.

    Long:
    The type of arr in both TU aren't the same. The above arr is of int[2], the
    below is of int* . In terms of implementation, let sizeof(int)==4 and
    sizeof(int*)==8, and *array* *object* arr in the above TU is stored at
    0x12345678. When the TUs are linked together, func() thinks that a *pointer*
    *object* is stored at 0x12345678, so, the func() runs, it reads 8 bytes from
    0x12345678, that is, assuming little-endian machine, 0x0000020000000100 and
    try to dereference that address, of cause, the program crashes.
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.9 (GNU/Linux)

    iEYEARECAAYFAkt5YbsACgkQm4klUUKw07BrtwCfUOKZXPA932cL4jgqCP+g+Q6q
    UrwAmgIGxnubcQ7K1O21PsmBQX3jt425
    =tin7
    -----END PGP SIGNATURE-----
    Michael Tsang, Feb 15, 2010
    #2
    1. Advertising

  3. "" <> writes:

    > Guys,


    ....and gals.

    > Consider the following two files, files test.c and test1.c
    >
    > Contents of test1.c are as follows:
    > ---------------------------------------------------
    >
    > int arr[] = { 0x100, 0x200 };
    > int main(void)
    > {
    > printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
    > func();
    > }
    >
    > Contents of test1.c
    > ------------------------------
    > extern int *arr;


    In addition to the comments you've already had, if you don't want to
    commit yourself to the size, you can declare arr like this:

    extern int arr[];

    > func()
    > {
    > printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
    > }


    If this is C90 you need a return statement in main. If this is C99
    you can't have a function with return type declared using implicit
    int. Furthermore, both files need #include <stdio.h> and the format
    specifier should match the type of the arguments you are printing (x
    is for unsigned int).

    Some of these are all details, but what do you gain by playing fast a
    loose with the compiler? One day, one of these will bite you (but
    probably never the last).

    > The 2 files are compiled without any error, but when I run the
    > executable generated, it crashes with segmentation fault.


    You need to turn up the warning level and then some of the matters
    I've raised will be warned about. I prefer to be told!

    <snip>
    --
    Ben.
    Ben Bacarisse, Feb 15, 2010
    #3
  4. Eric Sosman Guest

    On 2/15/2010 9:47 AM, wrote:
    > Guys,
    > [...]


    RTFFAQ. Question 6.1, the very first in the "Arrays
    and Pointers" section.

    --
    Eric Sosman
    lid
    Eric Sosman, Feb 15, 2010
    #4
  5. Guest

    On Feb 15, 7:55 pm, Richard Heathfield <> wrote:
    > wrote:
    > > Guys,

    >
    > >    Consider the following two files, files test.c and test1.c

    >
    > > Contents of test1.c are as follows:
    > > ---------------------------------------------------

    >
    > > int arr[] = { 0x100,  0x200 };
    > > int main(void)
    > > {
    > >    printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
    > >    func();
    > > }

    >
    > > Contents of test1.c
    > > ------------------------------
    > > extern int *arr;

    >
    > Change this to:
    >
    > extern int arr[2];
    >
    > and all will be well.
    >
    > arr is an array, not a pointer. The difference is important.
    >
    > <snip>


    I understand the difference between the types of "arr" in two files.
    What I wanted to know is what the linker did when it encountered
    "extern int *arr"?
    First of all why it didn't give any error ?
    What value it assigned to "arr declared as integer pointer" ?
    When I print the value of "arr" (printf("arr=%p", arr)) in test1.c,
    value printed was 0x100.

    Can you please tell, why the (int *arr) was assigned value 0x100?
    , Feb 15, 2010
    #5
  6. Seebs Guest

    On 2010-02-15, <> wrote:
    > I understand the difference between the types of "arr" in two files.
    > What I wanted to know is what the linker did when it encountered
    > "extern int *arr"?


    Whatever it wanted?

    > First of all why it didn't give any error ?


    Why should it have?

    > What value it assigned to "arr declared as integer pointer" ?
    > When I print the value of "arr" (printf("arr=%p", arr)) in test1.c,
    > value printed was 0x100.


    > Can you please tell, why the (int *arr) was assigned value 0x100?


    It wasn't.

    Okay, here's the thing. You declared an int[] containing two values, so
    that looks like, in memory:
    0x100 0x200
    you then told something that, at that location, it would find a pointer.
    So the pointer was "0x100".

    This behavior depends on a lot of things, including the coincidence that
    pointers and ints are the same size, and not all linkers would have done
    it, but that's probably what happened.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    Seebs, Feb 15, 2010
    #6
  7. Seebs <> wrote:
    > <> wrote:
    > > I understand the difference between the types of "arr"
    > > in two files.
    > > What I wanted to know is what the linker did when it
    > > encountered "extern int *arr"?

    >
    > Whatever it wanted?
    >
    > > First of all why it didn't give any error ?

    >
    > Why should it have?


    Why shouldn't it have? It's a fair question! If they were in
    the same translation unit, the implementation would be required
    to issue a diagnostic.

    Of course, the answer is that, for historical reasons (which
    still exist today,) C implementations tend to operate in
    3 stages (well 2 and a bit): pre-processing, compilation and
    linking. Traditionally, type information was not passed to
    linkers [hence name mangling in most C++ implementations.]

    But these days, all sorts of debugging information is
    available. So the question of why the standard doesn't
    require a diagnostic in this case is a valid one IMO,
    even if it should be asked in comp.std.c.

    --
    Peter
    Peter Nilsson, Feb 15, 2010
    #7
  8. Seebs Guest

    On 2010-02-15, Peter Nilsson <> wrote:
    > But these days, all sorts of debugging information is
    > available. So the question of why the standard doesn't
    > require a diagnostic in this case is a valid one IMO,
    > even if it should be asked in comp.std.c.


    I think it's actually plenty topical here. I doubt that requirement will
    make it in "soon", because of the need for support for existing linkers. I'd
    personally like to see it, though.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    Seebs, Feb 15, 2010
    #8
  9. gwowen Guest

    On Feb 15, 9:39 pm, Peter Nilsson <> wrote:

    > But these days, all sorts of debugging information is
    > available. So the question of why the standard doesn't
    > require a diagnostic in this case is a valid one IMO,
    > even if it should be asked in comp.std.c.


    I would guess the answer is "because at the time the standard was
    first written, such a clause would have required almost every linker
    in the world to be rewritten at a fundamental level". Subsequent to
    that the answer is "backwards compatibility".
    gwowen, Feb 16, 2010
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Prowak

    Why oh why doesn't my data view work?

    David Prowak, Jan 30, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    724
    Alvin Bruney [MVP]
    Jan 30, 2004
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    859
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,757
    Smokey Grindel
    Dec 2, 2006
  4. Sara
    Replies:
    6
    Views:
    249
    John W. Krahn
    Apr 12, 2004
  5. PerlFAQ Server
    Replies:
    0
    Views:
    246
    PerlFAQ Server
    Apr 26, 2011
Loading...

Share This Page