views:

139

answers:

6

This is a best practices question. I am making an array

type * x = malloc(size*sizeof(type));

AFAIK sizeof gives a return value of size_t. Does that mean that I should use a size_t to declare, or pass around size? Also when indexing the array should I also use a size_t for the index variable? What is the best practice for these these? This is not something that they taught in school, and now that I'm getting into serious c++ I want to know.

Also if anyone has references of where I can find best practices for this kind of stuff it would be helpful? Kind of an etiquette for programmers book.

EDIT: The malloc should be cudaHostAlloc, or cudaMalloc, since I am developing a class that stores an array simultaneously on the device and host, and updates both at the same time. So malloc here is just a place holder for what I'll actually be doing.

+4  A: 

In reference to your follow-on question:

The best reference I have used for general high-level programming "current good practices" sort of thing is:

Code Complete by Steve McConnell (ISBN 0-7356-1967-0)

I reference it all the time. When my company formalized its coding standards, I wrote them based off of it. It doesn't go into design or architecture as much, but for actually banging out code, the book is appropriately named.

Nate
It's good, what does it say about this matter?
kotlinski
The end of the question says: "Also if anyone has references of where I can find best practices for this kind of stuff it would be helpful? Kind of an etiquette for programmers book." This is what I provided. I didn't realize that we were supposed to stick to the title of the question, and not stray to answering follow-on questions.
Nate
+1  A: 

Well, since you've already abandoned best practice, even GOOD practice, by using malloc...why does it really matter?

That said, I generally use size_t unless I need a type that can go negative for various semi-rare conditions.

Noah Roberts
+5  A: 

In general, I use whatever minimizes the number of implicit or explicit casts and warning errors. Generally there is a good reason why things are typed the way they are. size_t is a good choice for array index, since it's unsigned and you don't generally want to access myarray[-1], say.

btw since this is C++ you should get out of the habit of using malloc (free) which is part of CRT (C runtime library). Use new (delete), preferably with smart pointers to minimize manual memory handling.

Once you have mastered the basics, a good practices reference (language-specific) is Effective C++ by Scott Meyers. The logical next step is Effective STL.

Steve Townsend
One advantage with using int as an index is that you can iterate downwards and have a termination condition that checks if the index is >= 0.
kotlinski
True - or, you could use `array::rbegin()` and `array::rend()`
Steve Townsend
@steve - That is iff you've caught onto the best practice of using "smart" arrays rather than the raw types.
Noah Roberts
@Noah - even without that, it's possible (and faster) to use pointer arithmetic not indices. Many STL algorithms work with pointer ranges too.
Steve Townsend
I'd agree with that. Unfortunately I don't believe there's a pointer->iterator wrapper that would be necessary for a reverse iterator. I'm also not 100% sure iterating to one less than the start of an array is OK from the standard's POV. I seem to recall a big discussion somewhere at one point that resulted in the fact that some architectures can actually have problems with first-1 and last+2. For most purposes I doubt that matters though.
Noah Roberts
`myarray[4294967295]` is just as silly as `myarray[-1]`.
Inverse
@Inverse - yes but the point is to express intended semantics of the index variable, not *per se* to prevent bad code from being written.
Steve Townsend
In most cases it is better to use std::vector than new/delete
Ben
@Ben, agreed, but in context (OP is new to C++) new/delete is a good first step vs `malloc/free`. Since I see this is CUDA, I doubt `vector` is available.
Steve Townsend
A: 

If you are coding in C++, why are you using malloc anyways? That's just asking for trouble. If you are making an array, I'd be looking at Vector<> which bypasses the need for programmer managed memory completely. Seriously, anytime I find myself using a naked 'new' in code, I look closely to see why a smart pointer or container isn't in use instead. if done right, you never have to worry about delete, delete[], or even free again.

Michael Dorgan
+1  A: 

cudaMalloc takes a size of type size_t, so for consistency, that's what you should use for indices.

Steve M
A: 

I would prefer int over size_t for a couple reasons:

  1. primitive types should be preferred unless the typedef provides something fundamentally new, size_t here doesn't
  2. the size_t is defined differently on different systems, possibly creating surprises for some developers
  3. signed int avoids for (size_t i=9; i>=0; --i) bugs, as well as other bugs in conditionals, e.g. if (result < 1) or if ((i-2)/2 < 1)

size_t is a useless abstraction that masks undesired behavior by silencing underflows

Inverse
1. `size_t` is a standardized typedef for a primitive type. 2. `int` also varies from system to system. 3. A good compiler will warn you when you say `i >= 0` for an unsigned type. `int` masks undesired behavior by silencing overflows.
Adrian McCarthy