Allocated memory

Discussion in 'C++' started by john, Jun 8, 2004.

  1. john

    john Guest

    I have a similar code to the following, here is the simplified version. I
    didn't compile and run the following code, so don't worry about the syntax.
    My question is I memcpy a larger data (10Byte) to a smaller one (1B),
    however i can still access all the data (ref. to printf in the code). I
    suppose the stack size is usually big enough for this to happen (tell me
    otherwise). But what's the potential problem here?
    I thought it might screw up the pointer, mStruct.buf. But it's not. Is this
    legal? if not, why it's compliable? any problem here? thanks a lot.

    char tenChars[10];
    struct myStruct
    {
    int a;
    char oneChar[1];
    char * buf;
    }

    main()
    {
    struct myStruct mStruct;
    char tenChar[10];

    memset( tenChar, 1, 10);
    memcpy( mStruct.oneChar, &tenChars, 10);
    for (i=0; i<10; i++)
    printf("%c\n", buf;
    }


    ----------------------------------
    remove "(n.o---s.p.a.m)" to reply
     
    john, Jun 8, 2004
    #1
    1. Advertising

  2. "john" <john2000(n.o---s.p.a.m)@blueyonder.co.uk> wrote in message
    news:%r6xc.32548$...
    > I have a similar code to the following, here is the simplified version. I
    > didn't compile and run the following code, so don't worry about the

    syntax.
    > My question is I memcpy a larger data (10Byte) to a smaller one (1B),
    > however i can still access all the data (ref. to printf in the code). I
    > suppose the stack size is usually big enough for this to happen (tell me
    > otherwise). But what's the potential problem here?


    Your code writes past the end of mStruct.oneChar, which is undefined
    behavior. On some systems it might work, but on my system it dumps core --
    just like I expected.

    > I thought it might screw up the pointer, mStruct.buf. But it's not. Is

    this
    > legal? if not, why it's compliable? any problem here? thanks a lot.


    Just because it's undefined behavior doesn't mean it won't compile. Most C
    translators will give you enough rope to hang yourself without so much as a
    warning; taking care not to do so is _your_ responsibility, not the
    translator's.


    Various errors fixed below:

    > char tenChars[10];
    > struct myStruct
    > {
    > int a;
    > char oneChar[1];
    > char * buf;
    > }


    };

    > main()


    int main()

    > {
    > struct myStruct mStruct;
    > char tenChar[10];


    int i;

    > memset( tenChar, 1, 10);
    > memcpy( mStruct.oneChar, &tenChars, 10);
    > for (i=0; i<10; i++)
    > printf("%c\n", buf;


    printf("%c\n", mStruct.buf);

    > }



    S

    --
    Stephen Sprunk "Stupid people surround themselves with smart
    CCIE #3723 people. Smart people surround themselves with
    K5SSS smart people who disagree with them." --Aaron Sorkin
     
    Stephen Sprunk, Jun 8, 2004
    #2
    1. Advertising

  3. john

    Tim Orbaker Guest

    john wrote:
    > I have a similar code to the following, here is the simplified version. I
    > didn't compile and run the following code, so don't worry about the syntax.
    > My question is I memcpy a larger data (10Byte) to a smaller one (1B),
    > however i can still access all the data (ref. to printf in the code). I
    > suppose the stack size is usually big enough for this to happen (tell me
    > otherwise). But what's the potential problem here?
    > I thought it might screw up the pointer, mStruct.buf. But it's not. Is this
    > legal? if not, why it's compliable? any problem here? thanks a lot.


    In your example below, it is legal (see further note), but it's
    exceedingly bad form and may not work on all compilers.

    The reason this works is that myStruct is typically 12 bytes in size on
    a 32-bit machine and 24 bits in size on a 64-bit machine. This is
    structure padding. By aligning the fields in memory to match the machine
    word size, considerable(?) performance is gained.

    >
    > char tenChars[10];
    > struct myStruct
    > {
    > int a;
    > char oneChar[1];
    > char * buf;
    > }
    >
    > main()
    > {
    > struct myStruct mStruct;
    > char tenChar[10];
    >
    > memset( tenChar, 1, 10);


    Change this to: strncpy( tenChar, "0123456789", 10);

    > memcpy( mStruct.oneChar, &tenChars, 10);
    > for (i=0; i<10; i++)
    > printf("%c\n", buf;
    > }
    >


    Now, printing mStruct.oneChar[0] should show you either 4, or 8,
    depending upon your machine word size. Try the following (the results
    will vary based upon the endian-ness of your machine):

    printf( "%08x\n", mStruct.a ); // Should be something like 30313233
    printf( "%08x\n", (unsigned) mStruct.buf ); // Should be like 383900??


    >
    > ----------------------------------
    > remove "(n.o---s.p.a.m)" to reply
    >
    >
    >
    >
     
    Tim Orbaker, Jun 8, 2004
    #3
  4. john wrote:
    > I have a similar code to the following, here is the simplified version. I
    > didn't compile and run the following code, so don't worry about the syntax.
    > My question is I memcpy a larger data (10Byte) to a smaller one (1B),
    > however i can still access all the data (ref. to printf in the code). I
    > suppose the stack size is usually big enough for this to happen (tell me
    > otherwise). But what's the potential problem here?


    The problem is that you are moving data from a large container to
    a very small container. Just as reality and physics state, you have
    created undefined behavior. The container may overflow, it may break,
    it may explode.

    Why are you doing this?


    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c -faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.raos.demon.uk/acllc-c /faq.html
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
     
    Thomas Matthews, Jun 8, 2004
    #4
  5. On Tue, 8 Jun 2004, john wrote:

    > I have a similar code to the following, here is the simplified version. I
    > didn't compile and run the following code, so don't worry about the syntax.


    Why not take the few seconds to compile the code and try it. If it fails
    to work then you don't even need to ask this question here. If it does
    succeed then you can post code you know appears to be funcitonal.

    > My question is I memcpy a larger data (10Byte) to a smaller one (1B),
    > however i can still access all the data (ref. to printf in the code). I
    > suppose the stack size is usually big enough for this to happen (tell me
    > otherwise). But what's the potential problem here?


    It is undefined behaviour. Anything can happen.

    > I thought it might screw up the pointer, mStruct.buf. But it's not. Is this
    > legal? if not, why it's compliable? any problem here? thanks a lot.


    How do you know it is not trashing mStruct.buf? There is nothing in your
    code example to show it is not.

    > char tenChars[10];
    > struct myStruct
    > {
    > int a;
    > char oneChar[1];
    > char * buf;
    > }
    >
    > main()
    > {
    > struct myStruct mStruct;
    > char tenChar[10];
    >
    > memset( tenChar, 1, 10);
    > memcpy( mStruct.oneChar, &tenChars, 10);
    > for (i=0; i<10; i++)
    > printf("%c\n", buf;
    > }


    I'm unclear if you intended to create the global array tenChars and the
    local array tenChar. It could be on your implementation that this excessive
    allocation of memory is helping you. You are actually trashing the tenChar
    memory.

    I'm actually having to make assumptions about what you intended. I would
    believe it safe to assume the reference to buf should actually be
    mStruct.buf. I wonder why you are initializing tenChar with the memset
    and then copying the contents of tenChars (an uninitialized array) to
    mStruct.oneChar, using memcpy.

    I created the following program that does compile:

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

    char tenChars[] = "123456789";
    struct myStruct {
    int a;
    char oneChar[1];
    char *buf;
    };

    int main(void)
    {
    struct myStruct mStruct;
    char tenChar[] = "123456789";

    /* inialize the structure */
    mStruct.a = 0xdead;
    mStruct.buf = tenChar;
    printf("a: %x\tbuf: %p\n", mStruct.a, mStruct.buf);

    /* trash memory */
    memcpy(mStruct.oneChar, tenChars, 10);

    /* see that memory has been trashed */
    printf("a: %x\tbuf: %p\n", mStruct.a, mStruct.buf);

    return 0;
    }

    When I run it on my system, the value of mStruct.buf changes after the memcpy.
    Dereferencing mStruct.buf after the memcpy will definitely cause undefined
    behaviour. Since I have one instance that it fails to function as required,
    I would never do something like this.

    --
    Send e-mail to: darrell at cs dot toronto dot edu
    Don't send e-mail to
     
    Darrell Grainger, Jun 8, 2004
    #5
  6. john

    JKop Guest

    john posted:

    > I have a similar code to the following, here is the simplified version.
    > I didn't compile and run the following code, so don't worry about the
    > syntax. My question is I memcpy a larger data (10Byte) to a smaller one
    > (1B), however i can still access all the data (ref. to printf in the
    > code). I suppose the stack size is usually big enough for this to
    > happen (tell me otherwise). But what's the potential problem here?




    int *pJack = 0x9983;

    *pJack = 42;



    -JKop
     
    JKop, Jun 8, 2004
    #6
  7. john

    john Guest

    First of all, I found this from the software I'm working on. It's not
    written by me, so do not ask me why I wrote this.
    The code on the OP is just something I written from scratch to illustrate
    the whole thing. I don't want to copy the exact code, because it's not
    important and it might be distracting, and will be a long post (seems
    unavoidable now :)). So do not tell me the correction of code like Stephen
    and Darrell did. thanks anyway.

    I did made a mistake in the code (maybe is this causing the confusion,
    really sorry about that) which I intended to printf the oneChar instead of
    buf on the last line. as follows:
    printf("%c\n", mStruct.oneChar;
    the purpose is to tell you that I can access all the data copied from
    tenChar to oneChar. so the print out will be 10 ones as "1111111111".

    I put char *buf just to illustrate this pointer has NOT been corrupted due
    to stamping over by that "overflow copy". If I re-write it again, it will be
    like this (the data vars before the main() are the same):

    main()
    {
    struct myStruct mStruct;
    char tenChar[10];
    int d;

    mStruct.buf = &d;
    printf("%x\n", mStruct.buf); // let's say this will print "801a34bc"

    memset( tenChar, 1, 10);
    memcpy( mStruct.oneChar, &tenChars, 10);
    for (i=0; i<10; i++)
    printf("%c\n", mStruct.oneChar; // this will print "1111111111"

    printf("%x\n", mStruct.buf); // this will print "801a34bc"
    }

    As i said, I'm working for other people, and I can't tell them this is a bug
    because it doesn't do anything wrong. so I need to know how I can generate a
    fault with this, so that I can flag this as a bug and request a fix. that's
    why I was asking what are the potential problems, as I can use these to
    generate some faults. hopefully.

    I will answer each post separately.

    IMPORTANT BIT:
    Remember the whole idea/point/question is copying a larger array to a
    smaller one, what's potential problems?
    give some examples or code so that i can reproduce, be it crashing, data
    corruptions, whatever. Saying "undefine behaviour" is not what I lookin for,
    because I know that.

    "john" <john2000(n.o---s.p.a.m)@blueyonder.co.uk> wrote in message
    news:%r6xc.32548$...
    > I have a similar code to the following, here is the simplified version. I
    > didn't compile and run the following code, so don't worry about the

    syntax.
    > My question is I memcpy a larger data (10Byte) to a smaller one (1B),
    > however i can still access all the data (ref. to printf in the code). I
    > suppose the stack size is usually big enough for this to happen (tell me
    > otherwise). But what's the potential problem here?
    > I thought it might screw up the pointer, mStruct.buf. But it's not. Is

    this
    > legal? if not, why it's compliable? any problem here? thanks a lot.
    >
    > char tenChars[10];
    > struct myStruct
    > {
    > int a;
    > char oneChar[1];
    > char * buf;
    > }
    >
    > main()
    > {
    > struct myStruct mStruct;
    > char tenChar[10];
    >
    > memset( tenChar, 1, 10);
    > memcpy( mStruct.oneChar, &tenChars, 10);
    > for (i=0; i<10; i++)
    > printf("%c\n", buf;
    > }
    >
    >
    > ----------------------------------
    > remove "(n.o---s.p.a.m)" to reply
    >
    >
    >
    >
     
    john, Jun 10, 2004
    #7
  8. john

    john Guest

    Please read my reply to the OP first!

    "Thomas Matthews" <> wrote in
    message news:1mjxc.2351$e%...
    > The problem is that you are moving data from a large container to
    > a very small container. Just as reality and physics state, you have
    > created undefined behavior. The container may overflow, it may break,
    > it may explode.
    >

    If you know the scenarios, criteria that can cause overflow, or break, or
    explode in this case, that would be very helpful.

    > Why are you doing this?
    >

    As I explained earlier in my reply, I didn't do this, I found this. but it
    didn't give me trouble, that troubles me :(
     
    john, Jun 10, 2004
    #8
  9. john

    john Guest

    Please read my reply to the OP first!

    "Tim Orbaker" <> wrote in message
    news:...

    > In your example below, it is legal (see further note), but it's
    > exceedingly bad form and may not work on all compilers.
    >

    in this case, it works on mine

    > The reason this works is that myStruct is typically 12 bytes in size on
    > a 32-bit machine and 24 bits in size on a 64-bit machine. This is
    > structure padding. By aligning the fields in memory to match the machine
    > word size, considerable(?) performance is gained.
    >

    maybe it's a bad example, can you change the 10 bytes to 100 bytes, like
    this:
    char tenChars[100];
    Please don't take this as a wind up, the actual code that I'm working on
    copy more than 100 bytes. The reason I chose 10 bytes is no reason really,
    mainly to simplify the code, and the whole point is to illustrate copying
    from larger to smaller anyway.

    Nevertheless, you have some interesting point there. I will try this out.
    Why memcpy oneChar will override mStruct.a? because you said
    > printf( "%08x\n", mStruct.a ); // Should be something like 30313233



    > >
    > > char tenChars[10];
    > > struct myStruct
    > > {
    > > int a;
    > > char oneChar[1];
    > > char * buf;
    > > }
    > >
    > > main()
    > > {
    > > struct myStruct mStruct;
    > > char tenChar[10];
    > >
    > > memset( tenChar, 1, 10);

    >
    > Change this to: strncpy( tenChar, "0123456789", 10);
    >
    > > memcpy( mStruct.oneChar, &tenChars, 10);
    > > for (i=0; i<10; i++)
    > > printf("%c\n", buf;
    > > }
    > >

    >
    > Now, printing mStruct.oneChar[0] should show you either 4, or 8,
    > depending upon your machine word size. Try the following (the results
    > will vary based upon the endian-ness of your machine):
    >
    > printf( "%08x\n", mStruct.a ); // Should be something like 30313233
    > printf( "%08x\n", (unsigned) mStruct.buf ); // Should be like 383900??
    >
    >
    > >
    > > ----------------------------------
    > > remove "(n.o---s.p.a.m)" to reply
    > >
    > >
    > >
    > >

    >
     
    john, Jun 10, 2004
    #9
  10. john

    john Guest

    Please read my reply to the OP first!

    "Stephen Sprunk" <> wrote in message
    news:...

    > Your code writes past the end of mStruct.oneChar, which is undefined
    > behavior. On some systems it might work, but on my system it dumps

    core --
    > just like I expected.


    what causing the core dump on your system? afaik, there are few criteria for
    this, accessing a null pointer is on of them. I mean you should answer only
    if you know, it's a bit too difficullt job to find out anyway.
     
    john, Jun 10, 2004
    #10
  11. john

    john Guest

    Please read my reply to the OP first!

    "Darrell Grainger" <> wrote in message
    news:p...
    > On Tue, 8 Jun 2004, john wrote:
    >
    > Why not take the few seconds to compile the code and try it. If it fails
    > to work then you don't even need to ask this question here. If it does
    > succeed then you can post code you know appears to be funcitonal.
    >

    Hope you understand now. the code written here is not important. The actual
    code compiled and runs ok (maybe it's not ok, this is what I'm trying to
    find out).

    > It is undefined behaviour. Anything can happen.
    >

    If you can give some examples that you know of, that would be great.

    > How do you know it is not trashing mStruct.buf? There is nothing in your
    > code example to show it is not.
    >

    I should printf the "buf" in the code to clarify this.

    > I'm unclear if you intended to create the global array tenChars and the
    > local array tenChar. It could be on your implementation that this

    excessive
    > allocation of memory is helping you. You are actually trashing the tenChar
    > memory.
    >

    Oh, this is new to me. I will read the rest first.... now I have read the
    rest. but I still dont get it as how tenChar will get trashed. Will run the
    code and see.

    > I'm actually having to make assumptions about what you intended. I would
    > believe it safe to assume the reference to buf should actually be
    > mStruct.buf.

    correct assumption. But this is a mistake, I actually want to print
    mStruct.oneChar to illustrate I can access all the copied data.

    > I wonder why you are initializing tenChar with the memset
    > and then copying the contents of tenChars (an uninitialized array) to
    > mStruct.oneChar, using memcpy.
    >

    just to prove I can access all the copied data, so the print out will be
    "1111111111".

    > I created the following program that does compile:
    >

    no need for this, as it's only for illustration.

    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    >
    > char tenChars[] = "123456789";
    > struct myStruct {
    > int a;
    > char oneChar[1];
    > char *buf;
    > };
    >
    > int main(void)
    > {
    > struct myStruct mStruct;
    > char tenChar[] = "123456789";
    >
    > /* inialize the structure */
    > mStruct.a = 0xdead;
    > mStruct.buf = tenChar;
    > printf("a: %x\tbuf: %p\n", mStruct.a, mStruct.buf);
    >
    > /* trash memory */
    > memcpy(mStruct.oneChar, tenChars, 10);
    >
    > /* see that memory has been trashed */
    > printf("a: %x\tbuf: %p\n", mStruct.a, mStruct.buf);
    >
    > return 0;
    > }
    >
    > When I run it on my system, the value of mStruct.buf changes after the

    memcpy.
    > Dereferencing mStruct.buf after the memcpy will definitely cause undefined
    > behaviour. Since I have one instance that it fails to function as

    required,
    > I would never do something like this.
    >
    > --
    > Send e-mail to: darrell at cs dot toronto dot edu
    > Don't send e-mail to
     
    john, Jun 10, 2004
    #11
  12. "john" <john2000(n.o---s.p.a.m)@blueyonder.co.uk> wrote in message
    news:YeNxc.50592$...
    > Please read my reply to the OP first!
    >
    > "Stephen Sprunk" <> wrote in message
    > news:...
    > > Your code writes past the end of mStruct.oneChar, which is undefined
    > > behavior. On some systems it might work, but on my system it dumps
    > > core -- just like I expected.

    >
    > what causing the core dump on your system? afaik, there are few criteria

    for
    > this, accessing a null pointer is on of them. I mean you should answer

    only
    > if you know, it's a bit too difficullt job to find out anyway.


    When memcpy() writes past the end of mStruct.oneChar, it overwrites
    mStruct.buf with 0x01010101. When main() tries to dereference
    mStruct.buf to generate the argument to printf(), it accesses memory that
    doesn't belong to the process and thus triggers a segfault. This is just my
    analysis from reading the code, but I'll go through it with gdb if you want
    proof for your employer.

    My particular system is Linux 2.2.16 and gcc 2.91.66, but I'm surprised this
    isn't the result on every system with memory protection. In any case, it
    does invoke undefined behavior and should be considered a bug even if it
    mysteriously works on some systems.

    S

    --
    Stephen Sprunk "Stupid people surround themselves with smart
    CCIE #3723 people. Smart people surround themselves with
    K5SSS smart people who disagree with them." --Aaron Sorkin
     
    Stephen Sprunk, Jun 10, 2004
    #12
  13. On Thu, 10 Jun 2004 00:42:24 +0100, "john"
    <john2000(n.o---s.p.a.m)@blueyonder.co.uk> wrote:

    >First of all, I found this from the software I'm working on. It's not
    >written by me, so do not ask me why I wrote this.
    >The code on the OP is just something I written from scratch to illustrate
    >the whole thing. I don't want to copy the exact code, because it's not
    >important and it might be distracting, and will be a long post (seems
    >unavoidable now :)). So do not tell me the correction of code like Stephen
    >and Darrell did. thanks anyway.
    >
    >I did made a mistake in the code (maybe is this causing the confusion,
    >really sorry about that) which I intended to printf the oneChar instead of
    >buf on the last line. as follows:
    > printf("%c\n", mStruct.oneChar;
    >the purpose is to tell you that I can access all the data copied from
    >tenChar to oneChar. so the print out will be 10 ones as "1111111111".
    >
    >I put char *buf just to illustrate this pointer has NOT been corrupted due
    >to stamping over by that "overflow copy". If I re-write it again, it will be
    >like this (the data vars before the main() are the same):
    >
    >main()


    int main(void)

    >{
    > struct myStruct mStruct;
    > char tenChar[10];
    > int d;
    >
    > mStruct.buf = &d;
    > printf("%x\n", mStruct.buf); // let's say this will print "801a34bc"


    Let's not. Most of us prefer not to depend on undefined behavior. %x
    expects an int. You are passing it a pointer. If you want to print
    the value of a pointer, use %p and cast the value to void*.

    >
    > memset( tenChar, 1, 10);
    > memcpy( mStruct.oneChar, &tenChars, 10);


    Since memcpy takes pointers to void, the use of &tenChars doesn't hurt
    here but you really want to get in the habit of using the array name
    without an & in most situations like this. While you are at it,
    decide if the array name is tenChar or tenChars.

    > for (i=0; i<10; i++)


    i is undefined.

    > printf("%c\n", mStruct.oneChar; // this will print "1111111111"


    Not very likely. Did you try it? Each oneChar has the value
    integer 1. This is considerably different than the character value
    '1' which is what it would have to contain to match your comment.

    By the way, why do you think the \n will not force each character to a
    new line?

    >
    > printf("%x\n", mStruct.buf); // this will print "801a34bc"
    >}
    >
    >As i said, I'm working for other people, and I can't tell them this is a bug
    >because it doesn't do anything wrong. so I need to know how I can generate a


    It doesn't work now. How many more faults do you need?

    >fault with this, so that I can flag this as a bug and request a fix. that's
    >why I was asking what are the potential problems, as I can use these to
    >generate some faults. hopefully.
    >
    >I will answer each post separately.
    >
    >IMPORTANT BIT:
    >Remember the whole idea/point/question is copying a larger array to a
    >smaller one, what's potential problems?


    Tell them to look at every virus they have ever relieved. Most
    exploit some kind of buffer overrun, which is exactly what copying a
    large array to a small one is.

    >give some examples or code so that i can reproduce, be it crashing, data
    >corruptions, whatever. Saying "undefine behaviour" is not what I lookin for,
    >because I know that.
    >
    >"john" <john2000(n.o---s.p.a.m)@blueyonder.co.uk> wrote in message
    >news:%r6xc.32548$...
    >> I have a similar code to the following, here is the simplified version. I
    >> didn't compile and run the following code, so don't worry about the

    >syntax.
    >> My question is I memcpy a larger data (10Byte) to a smaller one (1B),
    >> however i can still access all the data (ref. to printf in the code). I
    >> suppose the stack size is usually big enough for this to happen (tell me
    >> otherwise). But what's the potential problem here?


    If you really want to be able to show them that it is broken, have
    them look at the generated assembler code. If they can't read that,
    then you do it and define several more variables so that some
    immediately follow the short array. Initialize one of these post
    array variables, print it, copy the long array to the short, then
    print the post array variable again and show them the changed value.

    You might also want to work on your resume since this head in the sand
    style of management will not survive in the long run. Remember the
    adage "those who wait for an accident before fixing anything are part
    of the problem, not part of the solution."

    >> I thought it might screw up the pointer, mStruct.buf. But it's not. Is

    >this


    You have no idea how much padding the compiler decided to insert
    between oneChar and buf.

    On my system when I ran your code, buf printed two different values:
    65fddc and 1010101. It did exactly what you expected. Why it doesn't
    on your system is something only you can determine.

    >> legal? if not, why it's compliable? any problem here? thanks a lot.


    You have the same problems copying the large array into the smaller
    one not defining i. Then you try to dereference buf when it was never
    initialized.

    I think there used to be a contest here about who could cram the most
    undefined behavior into the shortest code. I don't think you are near
    the record but if you practice...

    >>
    >> char tenChars[10];
    >> struct myStruct
    >> {
    >> int a;
    >> char oneChar[1];
    >> char * buf;
    >> }
    >>
    >> main()
    >> {
    >> struct myStruct mStruct;
    >> char tenChar[10];
    >>
    >> memset( tenChar, 1, 10);
    >> memcpy( mStruct.oneChar, &tenChars, 10);
    >> for (i=0; i<10; i++)
    >> printf("%c\n", buf;
    >> }




    <<Remove the del for email>>
     
    Barry Schwarz, Jun 10, 2004
    #13
  14. john

    Chris Torek Guest

    In article <%dNxc.50578$>
    john <john2000(n.o---s.p.a.m)@blueyonder.co.uk> writes:
    >The code [in my original post] is just something I written from
    >scratch to illustrate the whole thing. I don't want to copy the
    >exact code, because it's not important and it might be distracting,
    >and will be a long post ...


    >I did made a mistake in the [original example posting] code

    [followed by a new example that does not compile and clearly
    is not the problematic code].

    I think this deserves a parable. :)

    A man showed up at a veterinary office with a Persian house cat.
    "My pet is sick, can you help him?"

    The doctor examined the cat and told the man that the problem was
    simply a hairball, and that grooming and petromalt would typically
    solve the problem.

    "Oh no," the man exclaimed. "The problem isn't hairballs!"

    "I think it is," replied the vet. "This cat has no fever, and
    no signs of anything other than mild dehydration."

    "But you see," explained the main, "this isn't even my pet -- I
    have an elephant! I didn't bring him in because he's too big to
    fit in my car!"
    --
    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.
     
    Chris Torek, Jun 10, 2004
    #14
  15. "john" <john2000(n.o---s.p.a.m)@blueyonder.co.uk> wrote in message news:<%dNxc.50578$>...
    > IMPORTANT BIT:
    > Remember the whole idea/point/question is copying a larger array to a
    > smaller one, what's potential problems?
    > give some examples or code so that i can reproduce, be it crashing, data
    > corruptions, whatever. Saying "undefine behaviour" is not what I lookin for,
    > because I know that.

    Just explain behavior of following program :
    include <stdio.h>

    typedef struct Test{
    int one[1];
    volatile int size;
    int* buf;
    } Test;

    void initTest(Test* t, int size)
    {
    t->size = size;
    t->buf = t->one;
    for(int i=0;i<t->size;++i)t->one=i;
    }

    void printTest(Test* t)
    {
    for(int i = 0; i<t->size; ++i)
    {
    printf("%d\n",t->one);
    }
    printf("%p %p %d\n",(void*)t->one,(void*)t->buf,t->size);
    }

    int main(void)
    {
    Test t;
    initTest(&t, 1000);
    printTest(&t);
    return 0;
    }

    Greetings, Bane.
     
    Branimir Maksimovic, Jun 10, 2004
    #15
  16. john

    CBFalconer Guest

    Branimir Maksimovic wrote:
    >

    .... snip ...
    >
    > Just explain behavior of following program :
    > include <stdio.h>
    >

    .... snip code ...

    There is no explanation. It exhibits undefined behaviour, so it
    can do anything at all, including committing rape, arson, battery,
    and lies.

    Do not post C to c.l.c++, nor C++ to c.l.c.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Jun 10, 2004
    #16
  17. john

    Alan Johnson Guest

    CBFalconer wrote:

    >
    > There is no explanation. It exhibits undefined behaviour, so it
    > can do anything at all, including committing rape, arson, battery,
    > and lies.


    I'm sorry. Discussion of MSVC++ is off-topic here. ;-)

    Alan
     
    Alan Johnson, Jun 10, 2004
    #17
  18. john

    john Guest

    Actually you didn't tell the whole story, the more complete story is as
    followed:

    Before this man went to the vet with his cat. He actually did bring his
    elephant to lots of vet clinics. but he always get refused. Those vets don't
    even want to entertain him, just told this man we don't take elephants.

    "Chris Torek" <> wrote in message
    news:...
    > In article <%dNxc.50578$>
    > john <john2000(n.o---s.p.a.m)@blueyonder.co.uk> writes:
    > >The code [in my original post] is just something I written from
    > >scratch to illustrate the whole thing. I don't want to copy the
    > >exact code, because it's not important and it might be distracting,
    > >and will be a long post ...

    >
    > >I did made a mistake in the [original example posting] code

    > [followed by a new example that does not compile and clearly
    > is not the problematic code].
    >
    > I think this deserves a parable. :)
    >
    > A man showed up at a veterinary office with a Persian house cat.
    > "My pet is sick, can you help him?"
    >
    > The doctor examined the cat and told the man that the problem was
    > simply a hairball, and that grooming and petromalt would typically
    > solve the problem.
    >
    > "Oh no," the man exclaimed. "The problem isn't hairballs!"
    >
    > "I think it is," replied the vet. "This cat has no fever, and
    > no signs of anything other than mild dehydration."
    >
    > "But you see," explained the main, "this isn't even my pet -- I
    > have an elephant! I didn't bring him in because he's too big to
    > fit in my car!"
    > --
    > 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.
     
    john, Jun 10, 2004
    #18
  19. "CBFalconer" <> wrote in message
    news:...
    > Branimir Maksimovic wrote:
    > >

    > ... snip ...
    > >
    > > Just explain behavior of following program :
    > > include <stdio.h>
    > >

    > ... snip code ...
    >
    > There is no explanation. It exhibits undefined behaviour, so it
    > can do anything at all, including committing rape, arson, battery,
    > and lies.


    Yes it is undefined behavior, but... we can assume that
    arrays in C and C++ are laid in memory contiguously.
    Variable of type "volatile int", follows array of int,
    so we can assume that compiler will include side effect of buffer
    overrunning, resulting that value in *that* variable, will be visible
    in for loop (not cached), so program will not crash.:)
    How's that different from struct hacks which are widely spread
    around the globe?

    typedef struct Hack{
    // some elements
    char string[1];
    } Hack;

    .....
    const char* tmp = "Some thing";
    Hack* pHack = malloc(sizeof(Hack)+strlen(tmp));
    strcpy(pHack->string,tmp);
    .....

    >
    > Do not post C to c.l.c++, nor C++ to c.l.c.

    I thought that program will compile fine with both c++ and c99
    compilers. :) which part (of snipped code)is not C or C++?

    Greetings, Bane.


    P.S. this is just counter example, that is undefined behavior that
    "works". Perhaps OP's example is similar to struct hack but
    he haven't posted (or didn't understand) actual code.
     
    Branimir Maksimovic, Jun 11, 2004
    #19
  20. In article <caapdk$fgt$>,
    "Branimir Maksimovic" <> wrote:

    > "CBFalconer" <> wrote in message
    > news:...
    > > Branimir Maksimovic wrote:
    > > >

    > > ... snip ...
    > > >
    > > > Just explain behavior of following program :
    > > > include <stdio.h>
    > > >

    > > ... snip code ...
    > >
    > > There is no explanation. It exhibits undefined behaviour, so it
    > > can do anything at all, including committing rape, arson, battery,
    > > and lies.

    >
    > Yes it is undefined behavior, but... we can assume that
    > arrays in C and C++ are laid in memory contiguously.
    > Variable of type "volatile int", follows array of int,
    > so we can assume that compiler will include side effect of buffer
    > overrunning, resulting that value in *that* variable, will be visible
    > in for loop (not cached), so program will not crash.:)
    > How's that different from struct hacks which are widely spread
    > around the globe?
    >
    > typedef struct Hack{
    > // some elements
    > char string[1];
    > } Hack;
    >
    > ....
    > const char* tmp = "Some thing";
    > Hack* pHack = malloc(sizeof(Hack)+strlen(tmp));
    > strcpy(pHack->string,tmp);
    > ....
    >
    > >
    > > Do not post C to c.l.c++, nor C++ to c.l.c.

    > I thought that program will compile fine with both c++ and c99
    > compilers. :) which part (of snipped code)is not C or C++?
    >
    > Greetings, Bane.
    >
    >
    > P.S. this is just counter example, that is undefined behavior that
    > "works". Perhaps OP's example is similar to struct hack but
    > he haven't posted (or didn't understand) actual code.


    A good optimizing compiler will produce the same code for

    strcpy (pHack->string, tmp);
    and for
    pHack->string[0] = '\0';

    strcpy (pHack->string, tmp) has undefined behavior except if tmp points
    to an empty string. The compiler can assume that there is no undefined
    behavior and therefore tmp points to an empty string. If tmp points to
    an empty string, then strcpy will just set the first array element to
    '\0'. Therefore both statements are equivalent.
     
    Christian Bau, Jun 11, 2004
    #20
    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. Duncan
    Replies:
    0
    Views:
    403
    Duncan
    Jul 21, 2003
  2. Laura Heinzmann

    How to check memory size allocated to JVM?

    Laura Heinzmann, Feb 16, 2005, in forum: Java
    Replies:
    1
    Views:
    8,207
    John McGrath
    Feb 16, 2005
  3. Kjell Arne Johansen

    How do I know if memory is already allocated?

    Kjell Arne Johansen, Sep 1, 2003, in forum: C++
    Replies:
    8
    Views:
    401
    Kjell Arne Johansen
    Sep 2, 2003
  4. C++fan
    Replies:
    4
    Views:
    1,761
    Jack Klein
    Jan 7, 2004
  5. Replies:
    5
    Views:
    645
    Matt Wharton
    Dec 9, 2004
Loading...

Share This Page