memset doesn't work as expected

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • thomas

    memset doesn't work as expected

    I allocated a piece of memory and use memset to set it to 0.
    ------------------------------------
    int *graph = new int[16];
    memset(graph, 0, sizeof(graph));
    for(int i=0;i<4;i++){
    for(int j=0;j<4;j++)
    cout<<graph[i*n+j]<<" ";
    cout<<endl;
    }
    --------------------------------
    But I found that the output is really strange -- graph[0][1] is always
    a large number.
    I expected the output will all be 0.
  • thomas

    #2
    Re: memset doesn't work as expected

    or can I new a piece of memory and set it to zero in the mean time?

    Comment

    • Lars Uffmann

      #3
      Re: memset doesn't work as expected

      thomas wrote:
      I allocated a piece of memory and use memset to set it to 0.
      ------------------------------------
      int *graph = new int[16];
      memset(graph, 0, sizeof(graph));
      sizeof (graph) should be sizeof (int *) - which is definitely not sizeof
      (int)*16. So you are only setting the first sizeof(int *) bytes in the
      array to zero.

      Try memset (graph, 0, sizeof (int)*16) instead.

      Comment

      • peter koch

        #4
        Re: memset doesn't work as expected

        On 20 Feb., 13:28, thomas <FreshTho...@gm ail.comwrote:
        I allocated a piece of memory and use memset to set it to 0.
        ------------------------------------
        int *graph = new int[16];
        memset(graph, 0, sizeof(graph));
        for(int i=0;i<4;i++){
            for(int j=0;j<4;j++)
                cout<<graph[i*n+j]<<" ";
            cout<<endl;}
        >
        --------------------------------
        But I found that the output is really strange -- graph[0][1] is always
        a large number.
        I expected the output will all be 0.
        This is because you do not use std::vector. Always use high-level
        constructs unless you have a good reason not to: low level programming
        requires you to take care of lots of details that are irrelevant to
        your problem and might be difficult to get right. One of your problems
        here is that sizeof did not return what you thought, but there are
        other problems lurking!

        /Peter

        Comment

        • Lionel B

          #5
          Re: memset doesn't work as expected

          On Wed, 20 Feb 2008 04:35:26 -0800, peter koch wrote:
          On 20 Feb., 13:28, thomas <FreshTho...@gm ail.comwrote:
          >I allocated a piece of memory and use memset to set it to 0.
          >------------------------------------
          >int *graph = new int[16];
          >memset(graph , 0, sizeof(graph));
          >for(int i=0;i<4;i++){
          >    for(int j=0;j<4;j++)
          >        cout<<graph[i*n+j]<<" ";
          >    cout<<endl;}
          >>
          >--------------------------------
          >But I found that the output is really strange -- graph[0][1] is always
          >a large number.
          >I expected the output will all be 0.
          >
          This is because you do not use std::vector. Always use high-level
          constructs unless you have a good reason not to:
          Steady on, that could come across as somewhat patronising. You do not
          know for sure that the OP does not have a "good reason not to use a high-
          level construct". Ok, maybe unlikely in this case - but then again, to
          learn about (the dangers of) low-level constructs might be a valid reason
          to try them out and, as the OP has done, get some feedback on the results.
          low level programming
          requires you to take care of lots of details that are irrelevant to your
          problem and might be difficult to get right.
          Again: you don't know what the OP is trying to achieve (they don't say).

          --
          Lionel B

          Comment

          • Kai-Uwe Bux

            #6
            Re: memset doesn't work as expected

            Lars Uffmann wrote:
            peter koch wrote:
            >This is because you do not use std::vector. Always use high-level
            >constructs unless you have a good reason not to: low level programming
            >requires you to take care of lots of details that are irrelevant to
            >your problem and might be difficult to get right.
            >
            I fail to see a problem other than getting the size right in this
            case... Isn't speed always a "good reason" to do low level programming?
            No, there are many cases where speed is not a good reason to engage in low
            level programming.
            I am somewhat estranged here by your general "always use high-level
            constructs" statement.
            Well, if you leave out the "unless you have a good reason not to" part, the
            statement is false.


            [snip]


            Best

            Kai-Uwe Bux

            Comment

            • Andrew Koenig

              #7
              Re: memset doesn't work as expected

              "thomas" <FreshThomas@gm ail.comwrote in message
              news:43c0cc43-5f53-43e5-a0d6-b8b640998c00@e2 3g2000prf.googl egroups.com...
              >I allocated a piece of memory and use memset to set it to 0.
              ------------------------------------
              int *graph = new int[16];
              memset(graph, 0, sizeof(graph));
              Don't use memset. Your example shows one good reason: sizeof(graph) is the
              size of a pointer to int (because that's what graph is), so you will set to
              zero a number of bytes equal to the size of a pointer, which may or may not
              be the size of an int.

              If you insist on using new/delete instead of a vector, here's a cleaner way
              to do what you want:

              int *graph = new int[16];
              std::fill(graph , 16, 0);

              Note that you cannot use sizeof(graph) instead of 16. You can, however, do
              the following to avoid having to write 16 more than once:

              size_t graph_size = 16;
              int *graph = new int[graph_size];
              std::fill(graph , graph_size, 0);



              Comment

              • Lars Uffmann

                #8
                Re: memset doesn't work as expected

                Richard Herring wrote:
                >What does POD mean?
                Plain Old Data, though on looking more closely what I meant isn't
                exactly what the standard defines as POD.
                *pling* a-haaa :)
                I meant some type where all-bits-zero doesn't equate to having value
                zero, or whose constructor actually needs to do something.
                Oh, okay, I get it. Thanks - I'm too much used to i386 architectures :)

                Thanks!

                Lars

                Comment

                • red floyd

                  #9
                  Re: memset doesn't work as expected

                  Andrew Koenig wrote:
                  "thomas" <FreshThomas@gm ail.comwrote in message
                  I can't believe I'm correcting Andrew Koenig!!!!
                  Don't use memset. Your example shows one good reason: sizeof(graph) is the
                  size of a pointer to int (because that's what graph is), so you will set to
                  zero a number of bytes equal to the size of a pointer, which may or may not
                  be the size of an int.
                  >
                  If you insist on using new/delete instead of a vector, here's a cleaner way
                  to do what you want:
                  >
                  int *graph = new int[16];
                  std::fill(graph , 16, 0);
                  std::fill_n(gra ph, 16, 0);
                  or
                  std::fill(graph , graph+16, 0);
                  >
                  Note that you cannot use sizeof(graph) instead of 16. You can, however, do
                  the following to avoid having to write 16 more than once:
                  >
                  size_t graph_size = 16;
                  int *graph = new int[graph_size];
                  std::fill(graph , graph_size, 0);
                  >
                  again:

                  std::fill_n(gra ph, graph_size, 0);
                  or
                  std::fill(graph , graph+graph_siz e, 0);



                  Comment

                  • peter koch

                    #10
                    Re: memset doesn't work as expected

                    On 20 Feb., 14:02, Lionel B <m...@privacy.n etwrote:
                    On Wed, 20 Feb 2008 04:35:26 -0800, peter koch wrote:
                    On 20 Feb., 13:28, thomas <FreshTho...@gm ail.comwrote:
                    I allocated a piece of memory and use memset to set it to 0.
                    ------------------------------------
                    int *graph = new int[16];
                    memset(graph, 0, sizeof(graph));
                    for(int i=0;i<4;i++){
                        for(int j=0;j<4;j++)
                            cout<<graph[i*n+j]<<" ";
                        cout<<endl;}
                    >
                    --------------------------------
                    But I found that the output is really strange -- graph[0][1] is always
                    a large number.
                    I expected the output will all be 0.
                    >
                    This is because you do not use std::vector. Always use high-level
                    constructs unless you have a good reason not to:
                    >
                    Steady on, that could come across as somewhat patronising. You do not
                    know for sure that the OP does not have a "good reason not to use a high-
                    level construct".
                    I do know for sure. For the post of Thomas shows beyond doubt that he
                    is a beginner using C++ and probably also a beginner wrt programming.
                    Ok, maybe unlikely in this case - but then again, to
                    learn about (the dangers of) low-level constructs might be a valid reason
                    to try them out and, as the OP has done, get some feedback on the results.
                    I did give him feedback. Not only the important one (to stay away from
                    low-level stuff) but also why his program did not work.
                    >
                    low level programming
                    requires you to take care of lots of details that are irrelevant to your
                    problem and might be difficult to get right.
                    >
                    Again: you don't know what the OP is trying to achieve (they don't say).
                    I might not know what the OP is trying to achieve in details, but if
                    it is not related to the problem he is asking there's something fishy
                    going on!

                    /Peter

                    Comment

                    • James Kanze

                      #11
                      Re: memset doesn't work as expected

                      On Feb 20, 2:30 pm, Richard Herring <junk@[127.0.0.1]wrote:
                      In message <622mgcF20636.. .@mid.dfncis.de >, Lars Uffmann
                      <a...@nurfuersp am.dewrites
                      [...]
                      I currently see no other problems...
                      Until he decides to switch from int to some user-defined type
                      that isn't POD...
                      Theoretically, at least, memset of 0 doesn't even work for all
                      POD types. The only thing it's guaranteed to work for are
                      integral types (and I'm not even sure about those---int's can
                      have padding bits as well).

                      In practice, there have been machines where null pointers
                      didn't have all bits 0.

                      --
                      James Kanze (GABI Software) email:james.kan ze@gmail.com
                      Conseils en informatique orientée objet/
                      Beratung in objektorientier ter Datenverarbeitu ng
                      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                      Comment

                      • James Kanze

                        #12
                        Re: memset doesn't work as expected

                        On Feb 20, 2:02 pm, Lionel B <m...@privacy.n etwrote:
                        On Wed, 20 Feb 2008 04:35:26 -0800, peter koch wrote:
                        On 20 Feb., 13:28, thomas <FreshTho...@gm ail.comwrote:
                        I allocated a piece of memory and use memset to set it to 0.
                        ------------------------------------
                        int *graph = new int[16];
                        memset(graph, 0, sizeof(graph));
                        for(int i=0;i<4;i++){
                        for(int j=0;j<4;j++)
                        cout<<graph[i*n+j]<<" ";
                        cout<<endl;}
                        --------------------------------
                        But I found that the output is really strange -- graph[0][1] is always
                        a large number.
                        I expected the output will all be 0.
                        This is because you do not use std::vector. Always use high-level
                        constructs unless you have a good reason not to:
                        Steady on, that could come across as somewhat patronising.
                        I think it comes across more as somewhat professional. The code
                        above does exactly what std::vector does (except that
                        std::vector does it correctly).

                        --
                        James Kanze (GABI Software) email:james.kan ze@gmail.com
                        Conseils en informatique orientée objet/
                        Beratung in objektorientier ter Datenverarbeitu ng
                        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                        Comment

                        • Lionel B

                          #13
                          Re: memset doesn't work as expected

                          On Wed, 20 Feb 2008 12:23:31 -0800, James Kanze wrote:
                          On Feb 20, 2:02 pm, Lionel B <m...@privacy.n etwrote:
                          >On Wed, 20 Feb 2008 04:35:26 -0800, peter koch wrote:
                          On 20 Feb., 13:28, thomas <FreshTho...@gm ail.comwrote:
                          >I allocated a piece of memory and use memset to set it to 0.
                          >------------------------------------
                          >int *graph = new int[16];
                          >memset(graph , 0, sizeof(graph));
                          >for(int i=0;i<4;i++){
                          > for(int j=0;j<4;j++)
                          > cout<<graph[i*n+j]<<" ";
                          > cout<<endl;}
                          >--------------------------------
                          >But I found that the output is really strange -- graph[0][1] is
                          >always a large number.
                          >I expected the output will all be 0.
                          >
                          This is because you do not use std::vector. Always use high-level
                          constructs unless you have a good reason not to:
                          >
                          >Steady on, that could come across as somewhat patronising.
                          >
                          I think it comes across more as somewhat professional.
                          Like he gets paid to post here? ;-)
                          The code above
                          does exactly what std::vector does (except that std::vector does it
                          correctly).
                          Of course. I wasn't disputing the advice, more the tone, which I thought
                          a bit snarky. Anyhow, no big deal.

                          --
                          Lionel B

                          Comment

                          • Andrey Tarasevich

                            #14
                            Re: memset doesn't work as expected

                            thomas wrote:
                            or can I new a piece of memory and set it to zero in the mean time?
                            Yes, in case of scalar types (as 'int'). You could just do

                            int *graph = new int[16]();

                            and that's it.

                            --
                            Best regards,
                            Andrey Tarasevich

                            Comment

                            • Andrey Tarasevich

                              #15
                              Re: memset doesn't work as expected

                              James Kanze wrote:
                              ...
                              Theoretically, at least, memset of 0 doesn't even work for all
                              POD types. The only thing it's guaranteed to work for are
                              integral types (and I'm not even sure about those---int's can
                              have padding bits as well).
                              ...
                              Zeroing integral objects with 'memset' became legal in C99 and only
                              after the first (first?) corrigendum. Formally, it is still not
                              guaranteed to work in C++ and C89/90.

                              --
                              Best regards,
                              Andrey Tarasevich

                              Comment

                              Working...