1

So I have an array of pointers that references 3 instances of a class, I need to create a function that gets the references to those 3 instances and returns it into that array.

Here is what I have been trying:

#include<cstdlib>
#include<cinttypes>
#include<random>

//Random number generator
uint8_t rand(uint8_t max){
    std::default_random_engine generator;
    std::uniform_int_distribution<uint8_t> distribution(0,max);

    return distribution(generator);
}

class MyClass{
    //...
}
myClass[100];

MyClass * getReferences(){ //What should the type of this be?
    MyClass * arrayOfPointers[3];

    for(uint8_t i=0;i<2;++i){
        arrayOfPointers[i]=&myClass[rand(2)];
    }

    return arrayOfPointers;
}

int main(){
    MyClass * arrayOfPointers[3]=getReferences();

    return EXIT_SUCCESS;
}
TriforceOfKirby
  • 181
  • 1
  • 1
  • 10
  • 1
    http://en.cppreference.com/w/cpp/container/array – user657267 Mar 05 '15 at 02:24
  • 5
    Use `std::vector` or `std::array` and your problems will disappear. – Neil Kirk Mar 05 '15 at 02:24
  • 1
    So you've got a local array on the stack and then you return a pointer to it. Function finishes. Array goes out of scope. Nothing works as expected. Probably the most duplicated question on SO after comparing strings in Java. – John3136 Mar 05 '15 at 02:26
  • possible duplicate of [Can a local variable's memory be accessed outside its scope?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – John3136 Mar 05 '15 at 02:28

2 Answers2

3

As mentioned you are returning a pointer to a local variable which is incorrect.

Use standard library containers to avoid the pitfalls and woes of C-style arrays.

std::array<MyClass *, 3> getReferences()
{
    std::array<MyClass *, 3> arrayOfPointers;

    for(int i=0; i < 2; ++i) // don't use tiny int types of small for loops. it's not faster and it's harder to maintain
    {
        arrayOfPointers[i] = &myClass[rand(2)];
    }

    return arrayOfPointers;
}

int main()
{
    std::array<MyClass *, 3> arrayOfPointers = getReferences();
}
Neil Kirk
  • 21,327
  • 9
  • 53
  • 91
  • I was unaware of there being a standard library container for arrays, thanks! Also, so there is no advantage to using a small int type for a for loop? What about using uint_fast8_t then? – TriforceOfKirby Mar 05 '15 at 13:40
  • @TriforceOfKirby Why do you want to use an 8-bit value at all? It means whenever you change the range of the for loop, you also have to check the counter type is big enough, which is enough possibility of error. What `uint_fast8_t` actually is, is up to the compiler. – Neil Kirk Mar 05 '15 at 14:04
  • Well I suppose I just don't want to allocate more memory than needed. I find it fairly easy to determine if the type is large enough at a glance; the types are guaranteed to be at least the size specified or larger correct? If it needs to be made larger it's only 1 number to change. – TriforceOfKirby Mar 05 '15 at 14:20
  • For ~3 bytes? Compiler is free to, and indeed may, secretly convert your byte to a 4-byte int (or some other type) as an optimization, as smaller types may be slower to process. This is my advice as a seasoned programmer. – Neil Kirk Mar 05 '15 at 14:47
  • In most compilers you can control optimization preferences. So is execution speed in general more important than memory usage? – TriforceOfKirby Mar 05 '15 at 16:50
  • When the saving is 3 bytes, yes. If you were storing 10,000 integers that were only 0-255, then it would be more sensible to store them as 8-bit. – Neil Kirk Mar 05 '15 at 17:02
  • Ok, so would it be sensible to use `uint_fast_t` types? As it will use the fastest type that is at least the specified width. Also, thanks for all the information. – TriforceOfKirby Mar 05 '15 at 17:41
  • A general for loop, I would use `int`. A for loop which needs to iterate over a data structure, I would use either iterators (preferably - removes all consideration of what counter type to use) or `size_t` – Neil Kirk Mar 05 '15 at 17:47
0

Returning a pointer to a local variable is incorrect in C++. It can lead in memory violation errors. If you want to return an array from the function you should use dynamic memory allocation. MyClass * arrayOfPointers = new MyClass[3];. Don't forget to delete it, after using. delete[] arrayOfPointers;

Semyon Tikhonenko
  • 3,872
  • 6
  • 36
  • 61
  • If you want to return an array from the function you should NOT use dynamic memory allocation using `new[]`. What bad advice! – Neil Kirk Mar 05 '15 at 02:31
  • Why? Probably, you should not if you use exceptions inside the function. – Semyon Tikhonenko Mar 05 '15 at 02:34
  • "Don't forget to delete it" - which is exactly why you shouldn't be throwing raw pointers around and hoping for the best. Return `std::vector` if you need a dynamic array; but for a tiny, fixed-size array like this, dynamic allocation is massively inefficient, so return a `std::array`. – Mike Seymour Mar 05 '15 at 02:34
  • Yes std::vector or std::array would be better. – Semyon Tikhonenko Mar 05 '15 at 02:35