Sign in to follow this  
Thirthe

[C++] how to check how much is allocated?

Recommended Posts

consider this code
void check(int& number_)
{
    int n;
    // n=?
    for(int i=0; i<n; i++){
        number_[i]= i;
    }
}

main()
{
    int *number= new int[10];
    fill(*number);
}

is there a way to set 'n' to how many elements were allocated in main()?

Share this post


Link to post
Share on other sites
Directly, no. Besides, references are not pointers, they do not allow either array indexing or pointer arithmetic.

There is an alternative:

void fill(std::vector& v)
{
for( int i=0 ; i< v.size() ; i++){
v[i]= i;
}
}

int main()
{
std::vector vec(10);
fill(vec);
}




In general, when using C++ one should not use new[] and delete[], one should use std::vector<>.

Share this post


Link to post
Share on other sites
Pass it as a parameter?


void check(int* number_, int size)
{
for(int i=0; i<size; i++){
number_[i]= i;
}
}

main()
{
int *number= new int[10];
fill(number, 10);
}




Also, you should really use std::vector instead of arrays.

Share this post


Link to post
Share on other sites
ah, ok. i was wondering, because i saw this as an assignment.

another question regarding std::vector.
except for their safety, why should i use them? are they as fast as arrays?
also, including the STL libs makes my executable bloated, doesn't that affect the performance, as well?

ty.

Share this post


Link to post
Share on other sites
Quote:
Original post by Thirthe
ah, ok. i was wondering, because i saw this as an assignment.

another question regarding std::vector.
except for their safety, why should i use them? are they as fast as arrays?
also, including the STL libs makes my executable bloated, doesn't that affect the performance, as well?

ty.


In release mode, std::vector instances are as fast as dynamically allocated arrays. I expect that your compiler/linker would cut a lot of the bloat when compiling in release mode too.

Share this post


Link to post
Share on other sites
Quote:

Original post by ColeFreeman
Any in-depth reason for this?


For what? Passing the size as a parameter? How else would you do it?

Or are you asking why std::vector is a better choice? In that case, automatic memory management (resizing and cleanup) and the ability to be used in STL algorithms are some of the reasons. In general, they are superior to arrays because when working with them you don't have to worry about various low-level details (memory management, tracking the current element, maintaining the size, etc.). In other words, vectors allow you to work at a higher level of abstraction.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
In release mode, std::vector instances are as fast as dynamically allocated arrays. I expect that your compiler/linker would cut a lot of the bloat when compiling in release mode too.


Provided, of course, you don't use a compiler that uses checked iterators in release mode or turn them off if it does.

Though, in general, there are compiler dependent mechanisms for determining the size of a memory block at runtime. For example, MSVC provides _msize(), which will let you know the size of a block allocated by malloc(). However, if you find yourself needing to use them, chances are your design needs work.

Share this post


Link to post
Share on other sites
Rip-off: Yes, arrays are indeed evil it seems from certain perspectives, however I myself find myself drawn to them due to their simplicity, and I have to try better to re-evaluate the need for them in some situations. I am just afraid of the bloat from any pre-constructed code that needs to be small and lightning fast for very specific purposes.

Gage64: Yes I meant the vector<->array dilemma, however I noticed some huge benefits now that you guys mentioned them, aswell as the link posted by Rip-off. Clearly beneficial in some situations, I have a hard time putting them aside all together tho.

Thank you for the insight guys, it may prove very useful.

Share this post


Link to post
Share on other sites
Back to the original question. Unless i miss understand, you could pass a pointer to the check function and have that look 16 bytes before the pointer address (which contains the size of the allocation in bytes as a 4 byte integer if i remember correctly). If you also pass the size of the array type (in this case 4 bytes) you can divide the allocation size by that and get the number of elements in the array.

This makes me want to throw up though.

EDIT:

While we're on the topic of arrays, you should use boost::array. It acts as an array with bounds checking in debug and a plain c array in release.

Share this post


Link to post
Share on other sites
Quote:

Original post by Dave
you could pass a pointer to the check function and have that look 16 bytes before the pointer address (which contains the size of the allocation in bytes as a 4 byte integer if i remember correctly). If you also pass the size of the array type (in this case 4 bytes) you can divide the allocation size by that and get the number of elements in the array.


Is this portable behavior? Even if it is, it is probably only true for dynamically allocated arrays, so doing that will limit the applicability of the function.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
...the ability to be used in STL algorithms...


Arrays can actually be used in the Standard C++ Library algorithms.

Quote:

I am just afraid of the bloat from any pre-constructed code that needs to be small and lightning fast for very specific purposes.


Smells of premature optimisation. Write good, clean code first. If profiling later turns said code up as a hotspot, then try optimising.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
Quote:

Original post by Dave
you could pass a pointer to the check function and have that look 16 bytes before the pointer address (which contains the size of the allocation in bytes as a 4 byte integer if i remember correctly). If you also pass the size of the array type (in this case 4 bytes) you can divide the allocation size by that and get the number of elements in the array.


Is this portable behavior? Even if it is, it is probably only true for dynamically allocated arrays, so doing that will limit the applicability of the function.


I forgot to mention, yes this is only for dynamically allocated memory, as far as i know.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dave
Back to the original question. Unless i miss understand, you could pass a pointer to the check function and have that look 16 bytes before the pointer address (which contains the size of the allocation in bytes as a 4 byte integer if i remember correctly). If you also pass the size of the array type (in this case 4 bytes) you can divide the allocation size by that and get the number of elements in the array.


That's bad advice in so many different ways I can't even begin to count. For one thing, many implementations of memory managers work by simply wrapping OS operating system allocation routines. For example, on Windows, it might wrap (eventually) RtlAllocateHeap(), where the size is stored 8 bytes before the allocation, as a two byte integer, in qwords (not bytes). The sad thing is, that advice might work with MSVC in debug mode. And then crash and burn when switching to release mode.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Quote:
Original post by Dave
Back to the original question. Unless i miss understand, you could pass a pointer to the check function and have that look 16 bytes before the pointer address (which contains the size of the allocation in bytes as a 4 byte integer if i remember correctly). If you also pass the size of the array type (in this case 4 bytes) you can divide the allocation size by that and get the number of elements in the array.


That's bad advice in so many different ways I can't even begin to count. For one thing, many implementations of memory managers work by simply wrapping OS operating system allocation routines. For example, on Windows, it might wrap (eventually) RtlAllocateHeap(), where the size is stored 8 bytes before the allocation, as a two byte integer, in qwords (not bytes). The sad thing is, that advice might work with MSVC in debug mode. And then crash and burn when switching to release mode.


Yep, which is why i said it makes me wanna throw up!

Share this post


Link to post
Share on other sites
My point being, you didn't bother identifying situations where it would actually work, and said it as if every C++ compiler in the entire world put size information exactly 16 bytes before the allocation as an exactly four byte integer. Guess what? That's not even close to true.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
My point being, you didn't bother identifying situations where it would actually work, and said it as if every C++ compiler in the entire world put size information exactly 16 bytes before the allocation as an exactly four byte integer. Guess what? That's not even close to true.


Quite correct. I didn't clarify at all.

Share this post


Link to post
Share on other sites
Quote:
I am just afraid of the bloat from any pre-constructed code that needs to be small and lightning fast for very specific purposes


boost::array, stack allocated.

That's as fast as it gets.

Share this post


Link to post
Share on other sites
Quote:
Original post by bluescrn
Is it stupid of me to avoid std::vector because code creating a std::vector of Engine::Vector (my mathematical kind of vector, used all over the place) could become hard to read?...


Well that can be an issue, but std::vector is too useful to avoid for that reason.

Besides most people name their mathematical vectors something along the line of vector2, vector3, vector4 etc, where the number describes how many components that vector class has.

Share this post


Link to post
Share on other sites
Quote:
Original post by bluescrn
Is it stupid of me to avoid std::vector because code creating a std::vector of Engine::Vector (my mathematical kind of vector, used all over the place) could become hard to read?...


This is what typedefs are for. Ex:

typedef std::vector<Engine::Vector> VectorArray;

Share this post


Link to post
Share on other sites
Quote:
Original post by fpsgamer
Besides most people name their mathematical vectors something along the line of vector2, vector3, vector4 etc, where the number describes how many components that vector class has.


Getting rather offtopic for this thread, but I did originally start out with a 'Vector4' class. Then realised that what I really wanted was a Vector3 with a 4th component for the few times it's needed (and for data alignment)

I didn't need to implement both a Vector3 and Vector4 class, as I've got no use for true 4D vectors (with full 4-component arithmetic) Most of the operations just operate on .xyz - so neither Vector3 or Vector4 seemed to be a good name for it... So it just became 'Vector'

(In the same way, I've just got 'Matrix', which is always 4x4, but has methods for 3x3 and 3x4 operations)



Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this