0

I'm trying to write a function that casts an array of ints into doubles. It takes in a constant pointer to the original int[] array (to avoid unwanted modifications?) and returns a pointer to an array of casted double[]. However, the code that I wrote doesn't seem to be working. Can anyone point out what's wrong with it?

#include <iostream>
using namespace std;
double* castToDouble(const int *input);

int main(){
    int integers[] = {1,2,3,4};
    double *doubles = castToDouble(integers);
    cout << "numElements in doubles: " << sizeof(doubles)/sizeof(double) << endl;
    for(int i = 0; i < sizeof(doubles)/sizeof(double); i++){
       cout << doubles[i] << endl;
    }
    return 0;
}

double* castToDouble(const int *input){
    // Obtain the number of elements in input.
    int numElements = sizeof(input)/sizeof(int);
    double *doubleAry = new double[numElements];
    cout << "numElements in input: " << numElements << endl;
    for(int i = 0; i < numElements; i++){
        doubleAry[i] = static_cast<double>(input[i]);
    }
    return doubleAry;
}

The output of the program is the following:

numElements in input: 2
numElements in doubles: 1
1

The numElements' calculated seem to be arbitrary too. I'm pretty new to c++ and am unable to pinpoint the problem. Thanks in advance.

ddolce
  • 739
  • 2
  • 10
  • 30
  • `sizeof(input)/sizeof(int)` doesn't give the size of array. It is equivalent to `sizeof(int*)/sizeof(int)` – Jarod42 Mar 23 '15 at 14:02
  • Having only a pointer to the first element, it is not possible to determine how many elements are pointed to. `sizeof(doubles)/sizeof(double)` doesn't work properly in this context. – Chad Mar 23 '15 at 14:02
  • 2
    You should stop using this `sizeof` nonsense. Either pass the size of the array as a separate argument, or switch to `std::vector`. – Cory Kramer Mar 23 '15 at 14:03
  • @Cyber How do you pass the size of the array without using sizeof? I learned this from a C++ book... – ddolce Mar 23 '15 at 14:05
  • `sizeof x / sizeof *x` is a C thing. It should not be used in C++ because it silently gives the wrong result when you use something for `x` that is not an array. (This only works for arrays). In C it is used because there is no other option, but in C++ you can use a different construct which will fail to compile if `x` is not an array. – M.M Mar 23 '15 at 14:05
  • @ddolce As a second parameter, eg `double* castToDouble(const int* input, int numElements)` – Cory Kramer Mar 23 '15 at 14:06
  • 1
    @ddolce either re-read your book more carefully, or burn it. – M.M Mar 23 '15 at 14:06
  • 1
    @Cyber so should I just stop using `[]` and ALWAYS use `std::vector` from now on? – ddolce Mar 23 '15 at 14:09
  • 1
    @ddolce Only the Sith deal in absolutes :) Many times yes `std::vector` is what you want instead of a raw array. In general, [see this diagram](https://i.stack.imgur.com/ktdfc.png) to pick the correct container type – Cory Kramer Mar 23 '15 at 14:10
  • 1
    @Cyber I think this flow chart should have a startpoint along the lines of "So you think you should use something other than std::vector ?" std::vector is/should be the default container is many cases. – Félix Cantournet Mar 23 '15 at 14:23
  • Yes. I can't remember the last time I used raw C arrays in C++ code. I haven't used new/delete for years. If you think you need them, you find you almost certainly don't. It's a shame so many CS courses still seem to be teaching C style in C++ class as well. – Robinson Mar 23 '15 at 14:25

1 Answers1

1

As you marked it C++, I thought this might be more idiomatic:

#include <vector>
#include <algorithm>

std::vector<double> CastToDouble(std::vector<int> const & ints)
{
    auto doubles = std::vector<double>(ints.size());

    std::transform(ints.begin(), ints.end(), doubles.begin(), [](int value) -> double {
        return static_cast<double>(value);
    });

    return doubles;
}

int main(int argc, char* argv[])
{
    auto values = std::vector<int>() = { 
        1, 2, 3, 4
    };

    auto doubles = CastToDouble(values);
}
Robinson
  • 9,666
  • 16
  • 71
  • 115
  • Or even `std::vector CastToDouble(std::vector const & ints) { return {ints.begin(), ints.end()}; }` – Jarod42 Mar 25 '15 at 08:56