2

How to return a pointer to array and get values from that?

int * getChange(int first[], int second[], int SIZE) {
    int i = 0;
    int * change = new int[2];
    for (i = 0; i < SIZE; i++) {
        if (first[i] != second[i]) {
            change[0] = first[i];
            change[1] = second[i];
        }
        break;
    }
    return change;
}

function main() {
    int myNumbers[] = {1, 0, 2, 3};
    int possibilities[] = {0, 1, 2, 3};
    int * change;
    change = getChange(possibilities, myNumbers, 4);
    printf("%i / %i\n", (change), (change+1));
}

Unfortunately the function seems to return addresses, not values...

Radek Simko
  • 15,886
  • 17
  • 69
  • 107
  • 7
    I suggest that you get a basic C++ book, because this is wrong on so many levels. – Puppy Jan 25 '11 at 13:04
  • 1
    Did you know you've got your `break` statement outside your `if` test? You'll only go through the for loop once. I think it wants to be inside the `if` test, so you break at the first difference. – Chowlett Jan 25 '11 at 13:05
  • Do you *have* to use arrays or is this a learning exercise? – Tony Jan 25 '11 at 13:06
  • @Chowlett yeah, that's only typo... sorry. I have troubles with returing the pointer to array and getting values from it... – Radek Simko Jan 25 '11 at 13:07
  • 3
    Are you sure you're writing __C++__?? Last time I looked, `function main()` wasn't valid syntax in that language. And are you sure you want to return the __same__ array? Because if you do, then, even without knowing much C++, the keyword __new__ should definitely give you a clue that you are on the wrong track completely. And wherever there's `new` (or `new[]`), there should be `delete` (`delete[]`) somewhare. Or better yet: some RAII class. I can't help but have to second DeadMG here: __Get a [book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list).__ – sbi Jan 25 '11 at 13:15

6 Answers6

2

Try to change

printf("%i / %i\n", (change), (change+1));

to

printf("%i / %i\n", *(change), *(change+1));

In the printf function you need to use an int as parameters, not an int*. the change variable is a pointer. You must use *change and, using pointers arithmetics, *(change + 1)

Obviously, don't forget to free the allocated memory.

Philipp
  • 11,549
  • 8
  • 66
  • 126
jcalvosa
  • 46
  • 1
  • Please learn how to format code. There's a small help ("How to edit"/"How to format") floating to the right of the edit pane explaining some basics (and linking to further thorough explanations). I've also tried to somewhat fix the grammar in your posting. Feel free to revert those changes if I messed up anything by doing so. – sbi Jan 25 '11 at 13:34
  • Wouldn't `change[0]` and `change[1]` be more appropriate (and symmetrical with the corresponding code in the `getChange` function) ? – Victor Nicollet Jan 25 '11 at 15:32
2

In C++, you would not be using arrays (int[] or int*), because they are annoying in several ways: you have to pass around the SIZE, they're usually exception-unsafe (you have to catch the exception, delete the array, then re-throw the exception), and they're hard to use as class members properly. Either use a standard library container, or an iterator range.

The idiomatic way to do what you're trying to do would be to use iterators and pairs:

template <typename IT_1, typename IT_2>
std::pair<int,int> getChange(IT1 begin, IT1 end, IT2 begin2) 
{
  for (; begin != end; ++begin, ++begin2)
  {
    if (*begin != *begin2) return std::make_pair(*begin,*begin2);
  }
  return std::make_pair(0,0);
}

void main() {
    int myNumbers[] = {1, 0, 2, 3};
    int possibilities[] = {0, 1, 2, 3};
    std::pair<int,int> change = getChange(possibilities, possibilities + 4, 
                                          myNumbers);
    printf("%i / %i\n", change.first, change.second);
}

Note that the second sequence (myNumbers) is expected to be as least as long as the first sequence. If you're not comfortable with iterators and function templates yet, you can always use vectors instead:

std::pair<int,int> getChange(std::vector<int> a, std::vector<int> b) {
  for (int i = 0; i < a.size() && i < b.size(); ++i)
  {
    if (a[i] != b[i]) return std::make_pair(a[i],b[i]);
  }
  return std::make_pair(0,0);
}

void main() {
    int _myNumbers[] = {1, 0, 2, 3};
    int _possibilities[] = {0, 1, 2, 3};

    std::vector<int> myNumbers(_myNumbers,_myNuymbers+4), 
                     possibilities(_possibilities,_possibilities+4);

    std::pair<int,int> change = getChange(possibilities, myNumbers);
    printf("%i / %i\n", change.first, change.second);
}

While the latter may seem rather more verbose than the array version (after all, it's creating two arrays and then copying their values into the vectors), keep in mind that initializing an array from a constant is a fairly rare occurence: most of the time, arrays (and vectors) are initialized dynamically by a piece of code dedicated to just that. Such code can usually be used for both arrays and vectors with only minimal changes.

And, of course, you can typedef both std::pair<int,int> and std::vector<int> to shorter names if you end up using them a lot.

Victor Nicollet
  • 24,361
  • 4
  • 58
  • 89
2

As it has been said, your code is very wrong in very many levels. I'll try to explain.

First of all, if you want to return the same array, why are you creating a new one? What is it you want to do, exactly?

Second, that new you make is never getting free'd. After main() exits, all the memory of your application is going to be claimed by the OS, but you shouldn't rely on that.

The code that Chowlett wrote is correct (+1 for being nice and pointing out the allocation problem ;), so I'll just go through your code and point out stuff

for(int i = 0 ; i < size i++)
{
    if(first[i] != second[i])
    {
        change[0] = first[i];
        change[1] = second[i];
    }
    break;
}

that doesn't do what you want. It checks if first[0] is different from second[0], then hits the break whether this holds true or not. You want the break inside the if statement block.

then if you want to use an array's content, you have to index it with [], otherwise you refer to the memory address of the array and it's indexes. This means which's been said, that you want to do

printf("%d / %d", changed[0], change[1])

While what's been said above that using C++ vectors is "better" for this case than arrays, I don't think this is the right answer to your question. You seem to be learning how to use arrays, and arrays are a most important part of C and even C++ real life coding. You'll use them a lot, they are WAY faster than vectors, and many many many libraries that you'll deal with are written in plain C, so you'll have to use them.

Learn yourself a little bit of pointer arithmetics, and you'll be fine. Remember to free the memory you allocate, this isn't Java. remember that a in

int a[3];

is more like a

int *a;

than like a

int a;

which explains why you can also do

printf("%d / %d", *changed, *(changed + 1));

Read the kernighan and ritchie. Happy hacking


Lacrymology
  • 2,269
  • 2
  • 20
  • 28
1

I think I'd write it a bit differently (and note that I'm sticking to C-only concepts here - in C++ I would almost certainly do things a bit differently):

void getChange(int *first, int *second, int SIZE, int *change) {
    int i = 0;
    for (i = 0; i < SIZE; i++) {
        if (first[i] != second[i]) {
            change[0] = first[i];
            change[1] = second[i];
            break;
        }
    }

    return;    
}

function main() {
    int myNumbers[] = {1, 0, 2, 3};
    int possibilities[] = {0, 1, 2, 3};
    int change[2];
    getChange(possibilities, myNumbers, 4, change);
    printf("%i / %i\n", change[0], change[1]);
}

If you allocate change outside of getChange you solve potential memory leak problems.

Chowlett
  • 45,935
  • 20
  • 116
  • 150
0
printf("%i / %i\n", (change), (change+1));

This should be:

printf("%d / %d\n", *change, *(change + 1));
Benoit
  • 76,634
  • 23
  • 210
  • 236
0
int* functionReturningArray( int *inputArray, int size)
{
    int*outputArray = new int[20];
    return outputArray;
}

But it is much better to use vector in c++ then c style arrays. Because it protect you from a lot of errors and it is faster to write code using vector. Also such functionReturningArray is not very good because it returns just a pointer t othe first element of array but don't return size. You can return size and a pointer (two arguments) by predefining them and passing pointers to them to your function like this:

void f(int**outputArray, int *size)
{
    *outPutArray = new int[20];
    *size = 20;
}

And how it looks with a vector:

std::vector<int> func(const std::vector<int> &input)
{
    std::vector<int> output;
    output.push_back(5);
    return output;
}

You can also create the vector on a heap and return a pointer to it. But avoid using std::vector - use std::string instead

Andrew
  • 24,218
  • 13
  • 61
  • 90