468,457 Members | 1,621 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,457 developers. It's quick & easy.

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.
Feb 20 '08 #1
14 4753
or can I new a piece of memory and set it to zero in the mean time?
Feb 20 '08 #2
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.
Feb 20 '08 #3
On 20 Feb., 13:28, thomas <FreshTho...@gmail.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
Feb 20 '08 #4
On Wed, 20 Feb 2008 04:35:26 -0800, peter koch wrote:
On 20 Feb., 13:28, thomas <FreshTho...@gmail.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
Feb 20 '08 #5
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
Feb 20 '08 #6
"thomas" <Fr*********@gmail.comwrote in message
news:43**********************************@e23g2000 prf.googlegroups.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);

Feb 20 '08 #7
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
Feb 20 '08 #8
Andrew Koenig wrote:
"thomas" <Fr*********@gmail.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(graph, 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(graph, graph_size, 0);
or
std::fill(graph, graph+graph_size, 0);

Feb 20 '08 #9
On 20 Feb., 14:02, Lionel B <m...@privacy.netwrote:
On Wed, 20 Feb 2008 04:35:26 -0800, peter koch wrote:
On 20 Feb., 13:28, thomas <FreshTho...@gmail.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
Feb 20 '08 #10
On Feb 20, 2:30 pm, Richard Herring <ju**@[127.0.0.1]wrote:
In message <622mgcF20636...@mid.dfncis.de>, Lars Uffmann
<a...@nurfuerspam.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:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Feb 20 '08 #11
On Feb 20, 2:02 pm, Lionel B <m...@privacy.netwrote:
On Wed, 20 Feb 2008 04:35:26 -0800, peter koch wrote:
On 20 Feb., 13:28, thomas <FreshTho...@gmail.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:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Feb 20 '08 #12
On Wed, 20 Feb 2008 12:23:31 -0800, James Kanze wrote:
On Feb 20, 2:02 pm, Lionel B <m...@privacy.netwrote:
>On Wed, 20 Feb 2008 04:35:26 -0800, peter koch wrote:
On 20 Feb., 13:28, thomas <FreshTho...@gmail.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
Feb 22 '08 #13
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
Feb 22 '08 #14
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
Feb 22 '08 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by bob_jenkins | last post: by
21 posts views Thread by jacob navia | last post: by
14 posts views Thread by Patrick Kowalzick | last post: by
27 posts views Thread by volunteers | last post: by
22 posts views Thread by silversurfer2025 | last post: by
23 posts views Thread by AndersWang | last post: by
18 posts views Thread by Gaijinco | last post: by
reply views Thread by NPC403 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.