programming
October 29, 2008 9:54 AM   Subscribe

In C or C++, how can I input a number, perform some computations on it, and then have it be the size of my array?

For example,

#include
using namespace std;

int main()
{
int x;
int w;
cout << "Enter a number: ";
c in - w;

x=4*w;

int a[x];
a[0]=25;

cout << " " << a[0] << endl;

}

Obviously, this program doesn't work (and I know the cin line is wrong, just ignore that), but hopefully you get the idea of what I'm trying to do. Let me know if there is any way to do this. Thanks.






posted by amsterdam63 to Computers & Internet (10 answers total) 1 user marked this as a favorite
 
You need to create the array dynamically:

int* a = new int[x];

When you're done, it's good practice to free the memory:

delete[] a;
posted by christonabike at 10:03 AM on October 29, 2008


use new (and delete) in C++ or good ol' malloc() (and free())
posted by GuyZero at 10:04 AM on October 29, 2008


The C way (not recommended):
int *a = (int*)malloc(sizeof(int) * x);

The C++ way that uses the STL (recommended):
vector<int> a(x);
posted by zsazsa at 10:05 AM on October 29, 2008


In both languages, arrays and pointers are pretty much the same thing.

In C:
int siz = 14; /* 14 elements */
int *array = (int*)malloc(size*sizeof(int));
/* deallocate */
free(array);
In C++:
size_t siz = 14;
SomeClass *array = new SomeClass[siz];
// deallocate
delete [] array;
As zsazsa says above, use STL if you can.
posted by mkb at 10:07 AM on October 29, 2008


Any dynamic memory allocation eventually gets transformed into a malloc() whether it's STL, which uses new, or new, which uses malloc. If you can't handle calling malloc, don't use STL until you figure malloc() out. It's not hard. It's not like you have to call brk()/sbrk() by hand or anything. Once you know how malloc works then you can save time and trouble using STL.
posted by GuyZero at 10:47 AM on October 29, 2008


I see you've been asking a lot of elementary programming questions over the past year. C and C++ are valuable not for their expressive abilities, but for their symbiosis with the hardware. A function call in C can be as short as three instructions of record keeping, and so on. Learning how to do one specific thing is simple enough, but what's valuable is understanding the underlying systems that C/C++ run on.

The creation of arrays demands a mention of memory allocation. Local variables are created in the "stack", to keep a record of all function call nesting. Generally all that's needed to allocate memory on the stack is to add a number to the "stack pointer" to move it forward enough bytes when starting a new function call. This number is determined at compile time, and is therefore "static". When a function ends, the stack pointer is moved back and anything now beyond the pointer could be overwritten by future function calls.

What's needed is a "dynamic" memory allocation method. The new operator in C++, or the malloc operator in C. In contrast with stack allocation, dynamic memory is allocated in the "heap", and is long lived. As a result, there's an amount of record keeping done for you by the heap allocation operations underneath the hood to ensure nothing overlaps. If you do not free allocated memory when done with the memory, the heap will grow with unusable memory (this is called a "memory leak"). Garbage collectors find such unused data and free it for you, but only very bad ones can exist for C++. So make sure to free the memory in most every case.

The people above have provided a good set of simple examples.
posted by pwnguin at 10:59 AM on October 29, 2008


Longer explanation if you needed one:

The 'beginner' way is 'static' memory allocation: the code allocates blocks of memory before the program begins execution.

For your problem you need dynamic memory allocation -- allocate a block of memory during program execution. Key to this is the malloc() routine.

malloc ( int val1 ) is a C library subroutine that creates a contigous block of memory of size "val1" bytes. It also returns an pointer to the newly created block of memory.

int *b = ( int * ) malloc ( sizeof ( int ) *x );

To understand the statement, you can break it up as follows:

In the above line of code, we first execute "malloc (sizeof(int)*x)"

In the brackets, we first determine 'sizeof(int)', ie how many bytes are required to store an integer in your computer.

Then we do ( 'sizeof(int)'*x ), where 'x' is a variable holding the size of your array of integers. This operation will return the total number of bytes needed to hold your array.

'malloc( sizeof (int) *x ) will thus create the block of memory consisting of the calculated number of bytes.

'( int * ) malloc ( sizeof ( int ) *x )' -- here, (int *) will ensure that the pointer returned by the malloc() routine is 'cast' to an integer pointer.

Lastly, 'int *b = ( int * ) malloc ( sizeof ( int ) *x );' -- here *b, the memory pointer is assigned the value of the integer pointer we've acquired from the above 'cast' operation.

And you can now access your integer array elements by using b[0], b[1] etc.
posted by the_ancient_mariner at 11:03 AM on October 29, 2008


In C99 you can in fact declare
int a[len];
where len is some (potentially non-const) variable. This syntax appears to work for C++ in gcc 4.0.1 as well. It is not ISO standard C++, however. In this case you would have to allocate on the heap:
int *a = new int[len];
and delete it when it is no longer referenced:
delete[] a;
(otherwise you will leak memory). In C++ it is usually better to use a std::vector, however, which you can allocate using its constructor:
std::vector<int> v(len);
When v goes out of scope, it will be deallocated by its destructor, rather than requiring an explicit free. It can also dynamically change size after its creation. See the STL Vector documentation for more information about it.
posted by panic at 11:25 AM on October 29, 2008 [1 favorite]


You seem to be posting a lot of fairly basic C/C++ programming questions. Rather than asking on here, it would probably help you more in the long run to do more reading and experimentation; you'll learn how to quickly find most answers yourself.

For C++, Bruce Eckel's _Thinking in C++_ and Koenig's _Accelerated C++_ are both pretty good. (Other people will probably have more suggestions -- I strongly dislike C++.)

For C, _the C Programming Language_ by Kernighan and Ritche ("K&R") is a good start, and I also like _The Practice of Programming_ by Kernighan and Pike and _Practical C Programming_ by Steve Oualline.

If you're fairly new to programming, C/C++ are a poor fit for you, unless you're working in an extremely specific niche. You would probably be better served by starting with a language that has a tighter write/test/debug feedback loop (i.e., something that lets you interactively build inside an interpreter), that doesn't need you to understand an entire compiling/linking/etc. toolchain upfront, and spends far less time on low-level concerns such as memory management. (Python is my usual suggestion, with Mark Pilgrim's Dive into Python. It's readable free online.)
posted by trouserbat at 1:17 PM on October 29, 2008


In C++, instead of T *t = new T[sz] followed by delete[] t use std::vector<T> t(sz). (and prefer iterators and t.at(idx) to t[idx] to avoid undiagnosed indexing outside of the valid bounds of the array) (and build the vector dynamically when appropriate, they resize as you .push_back and so on) (and use other containers when they are most appropriate).

Instead of T *t=new T followed by delete t, use std::tr1::shared_ptr<T> t(new T) (or boost::shared_ptr if your C++ compiler doesn't have tr1) -- shared_ptr reference

Taken together, these will mostly free you from one major hassle of C++ compared to real language: manual deletion of allocated objects. However, they do tend to increase the length of type declarations, another major hassle of C++.
posted by jepler at 2:15 PM on October 29, 2008


« Older Al Qaeda's Web Presence   |   Is my home's water pressure (90 psi) too high? Newer »
This thread is closed to new comments.