8

Hey everyone. I am an experienced java programmer and am just learning C++.

Now I have a bit of a beginner's problem. I have an array variable x of type int.

The user will input the size of x in method B. I want to use x in method A.

void method A()
{
 using int x [] blah blah blah
}

void method B()
{
int n;
cin >>n;
int x [n]; // How can I use this int x in method A without getting error: storage size x is unknown.
// Or the error 'x' was not declared in this scope.
}

EDIT: Parameter passing isn't a solution I am looking for.

DOUBLE EDIT: I do know about the vector option, but my program is cramming on time. I am creating an algorithm where every millisecond counts.

BTW I found out a way of doing it.

int x [] = {}

method B();
method A () { blah blah use x}
method B () {/*int*/ x [n]}
6
  • 4
    Not directly answering your question, but do get a good book. Here is a list: stackoverflow.com/questions/388242/… Commented May 6, 2011 at 17:40
  • 2
    If I am reading your pseudo-code correctly, you have created an array as a local variable in method B. If that is the case, you should realize that the local x hides the definition of the global x. That is, the data you write to x in B won't affect the global x, and won't be visible in A. Commented May 6, 2011 at 17:56
  • 2
    What's with all the downvoting? I posted my answer before the EDIT2 was posted. Also, @Jimmy Huch: if every nanosecond counts, use an array. If every day not spent debugging counts, use std::vector or boost::scoped_array. Commented May 6, 2011 at 18:00
  • Sorry, an error in my code. in method B () it is supposed to be {x [n]} not int x [n] Commented May 6, 2011 at 18:08
  • Jimmy, your "way of doing it" doesn't really work. Those are two completely distinct x variables. Things you declare in B have no effect on what A can do or see. Your original method B isn't valid C++ anyway (regardless of what you do in method A). Commented May 6, 2011 at 18:12

6 Answers 6

9

If you actually want an array and not a vector, and you want that array dynamically sized at runtime, you would need to create it on the heap (storing it in a pointer), and free it when you're done.

Coming from Java you need to understand that there's no garbage collection in C++ - anything you new (create on the heap) in an object you will want to clean up in the destructor with delete.

class foo
{
    private:
    int *array;

    public:
    foo() { array = NULL; };
    ~foo()
    {
        if (array != NULL)
            delete [] array;
    }

    void createArray()
    {
        array = new int[5];
    }

};

More info at: http://www.cplusplus.com/doc/tutorial/dynamic/

Sign up to request clarification or add additional context in comments.

4 Comments

Finally someone who answers the question.
This is the correct answer. Others want to give a C-style declaration, but that is wrong. Good job, +1
This code basically reinvents vector, but doesn't prevent you from leaking memory in createArray in addition to not providing a copy constructor or assignment operator leading to all sorts of problems if you ever copy it.
Ah, so I should have answered the question he didn't ask, and later stated he didn't want. Then I should have worked up some complete class that didn't really have anything to do with the question. Got it. I'll remember that next time.
3

This is a version of your example that works in c++.

#include <iostream>

int *my_array;

void methodA(a,b){
     my_array[a] = b;
}

int methodB(){
     int n;
     std::cin >> n;
     my_array = new int[n];
}

int main(){
     int x;
     x = methodB();
     methodA(x-1, 20);
     delete [] my_array;
     return 0;
}

Comments

1

Use a vector:

std::vector<int> x(n);

then pass that to method A as an argument of type std::vector<int> const &.

Edit: Or make the vector a data member of your class and set it with:

size_t n;
std::cin >> n;
x.resize(n);

Comments

1

In C++ you can't directly size an array with a runtime value, only with constants.

You almost certainly want vector instead:

std::vector<int> x(n);

5 Comments

@Charles Ray In C++ I don't see any particular reason to complicate things with pointers when vector will do.
The question asked for an array, not a vector. That was my only consideration in my previous comment. According to OP, time is essential, so a vector would certainly NOT be useful.
@Charles Ray Dynamic allocation and pointers will be pretty much equally performant to vector, with more risk of screwing up the memory management. There's no way to use a normal C-array with a runtime determined size, which is what the OP asked for.
I managed to size an array with the variable n? My program works like a charm :)
I'd like to see some data to back up such a bold claim.
1

EDIT: flesh out answer.

I can't quite tell if you are trying to learn about arrays, or if you are trying to solve some practical problem. I'll assume the latter.

The only way for method A to have access to any variable is if it is in scope. Specifically, x must either be:

  • a local, including a parameter (but you said no to parameter passing)
  • a class member, or
  • a global

Here is a solution in which x is a class member:

class C {
public:
  std::vector<int> x;
  void A() {
    std::cout << x[2] << "\n"; // using x[], for example.
  }
  void B() {
    int n;
    cin >> n;
    x = std::vector<int>(n); // or, as others have pointed out, x.resize(n)
  }
};

3 Comments

Why do you have a std:: prefix to the vector declarations?
Because the type vector is only available in the std namespace. If I didn't do that, I would get an undefined symbol error at compile time.
I see. I have already become accustomed to putting using namespace std; at the beginnning of every program
0

Be aware that arrays in C++ are much more basic (and dangerous) than in Java.

In Java, every access to an array is checked, to make sure the element number you use is within the array.

In C++, an array is just a pointer to an allocated area of memory, and you can use any array index you like (whether within the bounds of the array, or not). If your array index is outside the bounds of the array, you will be accessing (and modifying, if you are assigning to the array element!) whatever happens to be in memory at that point. This may cause an exception (if the memory address is outside the area accessible to your process), or can cause almost anything to happen (alter another variable in your program, alter something in the operating system, format your hard disk, whatever - it is called "undefined behaviour").

When you declare a local, static or global array in C++, the compiler needs to know at that point the size of the array, so it can allocate the memory (and free it for you when it goes out of scope). So the array size must be a constant.

However, an array is just a pointer. So, if you want an array whose size you don't know at compile time, you can make one on the heap, using "new". However, you then take on the responsibility of freeing that memory (with "delete") once you have finished with it.

I would agree with the posters above to use a vector if you can, as that gives you the kind of protection from accessing stuff outside the bounds of the array that you are used to.

But if you want the fastest possible code, use an allocated array:

class C {
 int [] x;

 void method A(int size)
 {
   x = new int[size];   // Allocate the array
   for(int i = 0; i < size; i++)
      x[i] = i;         // Initialise the elements (otherwise they contain random data)
   B();
   delete [] x;         // Don't forget to delete it when you have finished
                        // Note strange syntax - deleting an array needs the []
 }

 void method B()
 {
   int n;
   cin >> n;
   cout << x[n];
   // Be warned, if the user inputs a number < 0 or >= size, 
   // you will get undefined behaviour!
  }
}

2 Comments

Wrong. new and delete can be one of the slowest parts of the whole system - typically they use malloc/free under the hood (plus whatever happens in the constructor for a c++ class, though that's not really relevant to the discussion). The amount of time it will take for malloc to find a free block of memory of the size you are requesting isn't deterministic - it can potentially take a really long time, so there's no guarantees. At least std::vector gives amortized time guarantees.
@George I am assuming however that once the array is actually initialised (i.e. once 'new' actually returns the memory), then it is faster than a vector? Or is that not the case?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.