Two C++ questions

A

Andre Kostur

Regardless, do you consider the following 'good style' or an 'accepted
idiom'?

// allocate raw memory for image bits
void * p = (void *)new char[image_size];

(Note: I'm using C-style casts for brevity, substitute C++ style casts
if you prefer, the underlying idea is the same.)

Um... why cast at all since you get the conversion to void * for free?
 
J

Jacek Dziedzic

Julie said:
Regardless of what the answer is, I'd say that this is a definite case of 'bad
style'.

Well, if memset() clears a 1GB array five times faster than
any other method (in my implementation, that is) it's not bad style,
it's efficiency. I'm not one who falls prey to over-optimizing
to gain microseconds, but when we're talking about minutes
(clearing an array within a tight loop), I can't resist using
memset(), if not going for an compiler-specific even-faster
alternative (out of scope of this ng, of course).
If you are going to use mem* functions, allocate the memory w/ malloc
and friends.

Now that I was "made sure" (thanks, John!) that clearing a new'ed
array is perfectly safe, I cannot accept your concept of having to
introduce one ugly-low-level-C'ism whenever I'm forced to use
another ugly-low-level-C'ism -- that's weird. Actually (I have
almost no C background) I cannot imagine a rationale for using
malloc() ever -- is there any? I'd rather use ::new and allocate
char's, at least I don't have to double check it didn't fail.

- J.
 
D

Dave Moore

Julie said:
Jeff said:
for me, it
is easier to consider allocations through new to be reserved for instances of
objects, and allocations through malloc to be raw memory.

It is good that you're keeping a conceptual line between raw memory and
typed memory. I don't think avoiding "new" for the raw memory is the
clearest way to express this, though. On the rare occasions when I
really want some raw memory, I typedef unsigned char to a type called
Byte, and work with Bytes as my raw memory. I've found type and
variable names the best places in my code to "self-document."

int main ( )
{
typedef unsigned char Byte;

Byte* raw_memory = new Byte[ 100 ];

// Work with raw memory...

delete [ ] raw_memory;
}
Derived * p = new Derived[15];

Try to explain in simple what p points to, and what you can and can't do w/ the
underlying allocated memory.

p points to the first element in an array of Derived objects.
Contrast that with:

char * c = new char[15];

c points to the first element in an array of char.

Right! Which, conceptually, should be treated differently than an allocated
block of raw memory.
Because Derived is not POD but char is.

Right! I understand that there are special-class types, but feel that it can
be a sticking point for new learners of the language. Personally, I have no
problem w/ it because I stated w/ C and therefore had a basic understanding of
the POD types.

Part of my point is that you have to treat char as a non-POD type AND as an
allocation type for general purpose (raw) memory.

As I've said before, I think of it being more beneficial to think of new as an
allocator of instances of types, and malloc as an allocator of raw (untyped)
memory. My use of malloc is few and far between, so when it does happen, it is
usually very localized or well defined, and I have no problem keeping track of
the allocation scheme.

As I've stated, I would have preferred that new provide a method by which raw
(untyped) memory could be allocated, rather than allocating chars and calling
it raw. I've proposed

void * p = new void[size_in_bytes];

as reasonable candidate for such, although I realize that no such beast will be
making it into the standard, nor is this the forum to discuss such features.

So if C++ doesn't deal directly with raw memory, then what is
std::raw_memory_iterator for? I thought it was explicitly for
stepping through bytes allocated like:

void *p = new char[user_defined_size];

Dave Moore
 
J

Julie

Andre said:
Julie said:
Regardless, do you consider the following 'good style' or an 'accepted
idiom'?

// allocate raw memory for image bits
void * p = (void *)new char[image_size];

(Note: I'm using C-style casts for brevity, substitute C++ style casts
if you prefer, the underlying idea is the same.)

Um... why cast at all since you get the conversion to void * for free?

I was including it for clarity and documentative purposes, making it clear to
the reader that I was deliberately storing in a void *.
 
O

Old Wolf

Julie said:
Raw memory allocated through new char[size]
should be considered 'bad style'.

I agree, if you mean that you prefer using std::vector to allocate
raw memory, as guaranteed by C++03:

std::vector<unsigned char> raw(200);
unsigned char *ptr = &raw[0];

This has the advantage of cleaning up automatically, and being
able to re-size and preserve the contents in an exception-safe manner.
 
B

Bill Seurer

Jacek said:
Well, if memset() clears a 1GB array five times faster than
any other method (in my implementation, that is) it's not bad style,
it's efficiency. I'm not one who falls prey to over-optimizing
to gain microseconds, but when we're talking about minutes
(clearing an array within a tight loop), I can't resist using
memset(), if not going for an compiler-specific even-faster
alternative (out of scope of this ng, of course).

Sometimes you have no choice but to throw style to the winds and do some
down and dirty programming to get something to run fast. That should be
the last choice though once you have already done it "nicely" and shown
(through profiling or whatever) that indeed this is a performance
problem spot *in the overall program*. So what if it takes 10 times as
long to initalize some big chunk of memory if that is 1/100,000th of the
run time of the program? Oft times people get lost in writing ugly code
to speed things up when in the end it doesn't actually make the program
run much faster.

Even then you should explain exactly WHAT and (more importantly) WHY you
are doing it so that when the next poor schmuck who comes along and has
to maintain your code isn't totally misled.
 

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,455
Latest member
Delilah Code

Latest Threads

Top