Two C++ questions

P

Pat

Hi,

1. Any faster method (other than for-loop) to initialize array?

2. Does there have similar C++ function to replace C's "fprintf"?

Thanks.

Pat
 
A

Allan Bruce

Pat said:
Hi,

1. Any faster method (other than for-loop) to initialize array?

2. Does there have similar C++ function to replace C's "fprintf"?

Thanks.

Pat

1) yes, depends which type of array you have though, e.g. char array, array
of ints/etc. or array of classes.

2) not exactly, fprintf is available in C++ using the <cstdio> header, or
you can use an fstream.

Allan
 
J

John Harrison

Pat said:
Hi,

1. Any faster method (other than for-loop) to initialize array?

C++ does not specify the speed of any operation. If you want to know which
of two methods is faster the only way is to try both and time them.

2. Does there have similar C++ function to replace C's "fprintf"?

It does not have a function as such, it has a whole library for doing output
called the iostream library. Here's a quick sample that writes a line to a
file called fred.txt.

ofstream output_file("fred.txt");
output_file << "a number " << 123 << '\n';

john
 
P

Pat

Thanks.

I want to initialize "int" and "double" arrays. In my program, they are very
big, more than 10000 entries.

Pat
 
J

John Harrison

Pat said:
Thanks.

I want to initialize "int" and "double" arrays. In my program, they are very
big, more than 10000 entries.

Pat

Are the arrays dynamically allocated, on the stack or global?

Are they constant size?

Does you want to initialise with a single value, with calculated values,
with values read from a file, what exactly?

All these details matter, so I can't say what I would do until I know a bit
more. Even then what I would do isn't necessarily the fastest way, even if
it were fastest on my system, it might not be fastest on your system.

Undoubtedly the fastest way is to initialise an array is to get the compiler
to do it for you, but whether this is possible or not depends on the details
like those I mentioned above.

John
 
P

Pat

John,

Initially, these arrays are allocated by "new". After some operations, I
want to re-initialize the arrays to a initial value, say L. They are
constant size.

Pat.
 
I

Ingo Nolden

Hi,

try the following:


const int SIZE = 10000;
int *iArray = new int[ SIZE ];

...

memset( iArray, 0, SIZE * sizeof( int ) );

to initialize with 0.





"Pat"
 
J

Jacek Dziedzic

Pat said:
John,

Initially, these arrays are allocated by "new". After some operations, I
want to re-initialize the arrays to a initial value, say L. They are
constant size.

You might want to look up memset() which is probably the fastest
way you can set a range of memory to repetitions of the same byte.
Someone gave an example already. This method is however hardly
useful for anything other than filling with zeroes or some other
byte-sized value (so if your L is greater than 255 or if the
array is not of ints, forget memset).

You may also gain some time using memcpy() which is used to
copy ranges of memory, if it suits your example. Both these
functions are quite ugly and low-level, but that's what you're
looking for, right?

HTH,
- J.
 
J

John Harrison

Pat said:
John,

Initially, these arrays are allocated by "new". After some operations, I
want to re-initialize the arrays to a initial value, say L. They are
constant size.

Pat.

I would use fill_n.

#include <algorithm>

std::fill_n(array, SIZE, value);

Works on int arrays and double arrays and any other sort of array. The other
possibility is memset for filling an int array with zero.

john
 
J

Julie

John said:
Pat said:
John,

Initially, these arrays are allocated by "new". After some operations, I
want to re-initialize the arrays to a initial value, say L. They are
constant size.
[snip]
The other
possibility is memset for filling an int array with zero.

My understanding is that you shouldn't be using any mem* function on _anything_
allocated w/ new.
 
J

Jacek Dziedzic

Julie said:
My understanding is that you shouldn't be using any mem* function on _anything_
allocated w/ new.

Is that really the case? If so, I have some code to fix :).
Can someone confirm it and explain the rationale behind it?

TIA,
- J.
 
A

Andre Kostur

Is that really the case? If so, I have some code to fix :).
Can someone confirm it and explain the rationale behind it?

By using the mem* family of functions on classes, you may be catching
implementation-specific pieces of your class, such as a potential 'vtable
pointer' that your implementation may use. By doing a memset(this, 0,
sizeof(*this));, you may whack that vtable pointer, and who knows what's
gonna happen when you then try to call a virtual function.....

Or, there may be other RTTI stuff in the memory space of the class. Who
knows.
 
C

Claudio Puviani

Julie said:
John said:
Pat said:
John,

Initially, these arrays are allocated by "new". After some operations, I
want to re-initialize the arrays to a initial value, say L. They are
constant size.
[snip]
The other possibility is memset for filling an int array with zero.

My understanding is that you shouldn't be using any mem* function on _anything_
allocated w/ new.

You shouldn't use mem*() on non-POD objects, regardless of how or where they're
allocated. There's nothing wrong with using mem*() functions on POD objects (or
arrays thereof), even if they're allocated with 'new'. Still, given a choice,
it's better to use the standard algorithms.

Claudio Puviani
 
J

Jacek Dziedzic

Andre said:
By using the mem* family of functions on classes, you may be catching
implementation-specific pieces of your class, such as a potential 'vtable
pointer' that your implementation may use. By doing a memset(this, 0,
sizeof(*this));, you may whack that vtable pointer, and who knows what's
gonna happen when you then try to call a virtual function.....

Or, there may be other RTTI stuff in the memory space of the class. Who
knows.

No, not _classes_, I'd never erase a _class_ with memset. But
Julie suggested you can't use mem*() on _anything_ created with
new. Is this really the case that doing something like

int *p=new int[1000000];
memset(p,0,sizeof(int)*1000000);

is a bad idea just because p was allocated with new?

- J.
 
J

John Harrison

No, not _classes_, I'd never erase a _class_ with memset. But
Julie suggested you can't use mem*() on _anything_ created with
new. Is this really the case that doing something like

int *p=new int[1000000];
memset(p,0,sizeof(int)*1000000);

is a bad idea just because p was allocated with new?

- J.

No, Julie was mistaken.

john
 
J

Jacek Dziedzic

Claudio said:
You shouldn't use mem*() on non-POD objects, regardless of how or where they're
allocated. There's nothing wrong with using mem*() functions on POD objects (or
arrays thereof), even if they're allocated with 'new'. Still, given a choice,
it's better to use the standard algorithms.

Unfortunately, at least in my implementation, clearing an 400MB array
array via memset() is faster than std::fill_n() by a factor of five.
Of course it's ugly and allows for filling with certain values only.

- J.
 
J

Jacek Dziedzic

Claudio said:
You shouldn't use mem*() on non-POD objects, regardless of how or where they're
allocated. There's nothing wrong with using mem*() functions on POD objects (or
arrays thereof), even if they're allocated with 'new'. Still, given a choice,
it's better to use the standard algorithms.

Now, that is some relief :). I've erased many an int array via memset
and most of these had been allocated by new. Glad I won't have to fix
that :).

Thanks for making it clear,
- J.
 
J

Julie

John said:
No, not _classes_, I'd never erase a _class_ with memset. But
Julie suggested you can't use mem*() on _anything_ created with
new. Is this really the case that doing something like

int *p=new int[1000000];
memset(p,0,sizeof(int)*1000000);

is a bad idea just because p was allocated with new?

- J.

No, Julie was mistaken.

john

I'd like to see something from the standard that explicitly states that POD
types allocated by new can be manipulated w/ mem* functions.

How about a struct of PODs, what is the 'rule' in that case.

Regardless of what the answer is, I'd say that this is a definite case of 'bad
style'. If you are going to use mem* functions, allocate the memory w/ malloc
and friends.
 
J

Julie

Claudio said:
Julie said:
John said:
John,

Initially, these arrays are allocated by "new". After some operations, I
want to re-initialize the arrays to a initial value, say L. They are
constant size. [snip]
The other possibility is memset for filling an int array with zero.

My understanding is that you shouldn't be using any mem* function on _anything_
allocated w/ new.

You shouldn't use mem*() on non-POD objects, regardless of how or where they're
allocated. There's nothing wrong with using mem*() functions on POD objects (or
arrays thereof), even if they're allocated with 'new'. Still, given a choice,
it's better to use the standard algorithms.

Claudio Puviani

This just stinks of bad design.

If you are going to use mem* functions, allocate the memory w/ malloc.

If you are going to use the std functions, allocate the memory w/ new.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,167
Messages
2,570,913
Members
47,454
Latest member
eibaloja

Latest Threads

Top