21

Is this correct ? This is compiled with g++ (3.4) sucessfully.

int main()
{
    int x = 12;
    char pz[x]; 
}
Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Janaka
  • 489
  • 1
  • 4
  • 23

6 Answers6

26

Here's your combination answer of all these other ones:

Your code right now is not standard C++. It is standard C99. This is because C99 allows you to declare arrays dynamically that way. To clarify, this is also standard C99:

#include <stdio.h>

int main()
{
    int x = 0;

    scanf("%d", &x);

    char pz[x]; 
}

This is not standard anything:

#include <iostream>

int main()
{
    int x = 0;
    std::cin >> x;
    char pz[x]; 
}

It cannot be standard C++ because that required constant array sizes, and it cannot be standard C because C does not have std::cin (or namespaces, or classes, etc...)

To make it standard C++, do this:

int main()
{
    const int x = 12; // x is 12 now and forever...
    char pz[x]; // ...therefore it can be used here
}

If you want a dynamic array, you can do this:

#include <iostream>

int main()
{
    int x = 0;
    std::cin >> x;

    char *pz = new char[x];

    delete [] pz;
}

But you should do this:

#include <iostream>
#include <vector>

int main()
{
    int x = 0;
    std::cin >> x;

    std::vector<char> pz(x);
}
GManNickG
  • 494,350
  • 52
  • 494
  • 543
16

G++ supports a C99 feature that allows dynamically sized arrays. It is not standard C++. G++ has the -ansi option that turns off some features that aren't in C++, but this isn't one of them. To make G++ reject that code, use the -pedantic option:

$ g++ -pedantic junk.cpp
junk.cpp: In function ‘int main()’:
junk.cpp:4: error: ISO C++ forbids variable-size array ‘pz’
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
15

Technically, this isn't part of C++. You can do variable length arrays in C99 (ISO/IEC 9899:1999) but they are not part of C++. As you've discovered, they are supported as an extension by some compilers.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
12

If you want a dynamic array on the stack:

void dynArray(int x)
{
    int *array = (int *)alloca(sizeof(*array)*x);

    // blah blah blah..
}
Jim Buck
  • 20,482
  • 11
  • 57
  • 74
  • 10
    It works, but I'd like to add the following quote from "man alloca": "The alloca() function is machine and compiler dependent; its use is discouraged." – Michael Aaron Safyan Jul 30 '09 at 05:11
8

Allocating arrays with variable length on the stack is a good idea, because it fast and doesn't fragment the memory. But C++ Standard unfortunately doesn't support it. You could do this by using template wrapper to alloca function. But using alloca is not really a standard conforming.

Standard way is to use std::vector with custom allocator if you want to avoid memory fragmentation and speedup memory allocations. Take a look on boost::pool_alloc for a good sample of fast allocator.

Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
1

Practically speaking, if you want to make a dynamic array you should use std::vector, as in:

#include <iostream>
#include <cstdlib>
#include <vector>

int main(int argc, char* argv[])
{
   int size;
   std::cin>>size;
   std::vector<int> array(size);
   // do stuff with array ...
   return 0; 
}

If you are just curious about the syntax, then what you are looking for is:

//...
int* array = new int[size];
// Do stuff with array ...
delete [] array;
//...

Neither of these are allocated with local storage. A dynamically sized array that is automatically allocated using local storage is not currently supported in standard C++, but is supported in the current C standard.

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • Doesn't new allocate memory on the heap? I was under the impression that OP wanted it allocated on the stack, given the title of the question. – mrduclaw Jul 30 '09 at 05:32
  • 1
    doesn't change the fact that vector is the correct solution. In this case, he can't have what he's asking for. Vector is the closest. (And no, I'm not considering alloca in a C++ context) – jalf Jul 30 '09 at 05:38
  • 3
    For applications that need critical performance in certain cases, alloca is absolutely the right answer if the compiler does not support the "int array[x]" syntax. Stack-based allocations, typically just a single instruction subtracting from the stack pointer, are way faster than heap counterparts. – Jim Buck Jul 30 '09 at 05:45
  • As I said, neither of them use local storage (the stack), but rather dynamic storage (the heap). As an aside, if I remember correctly, the C++ standard specifically does not mention the stack or the heap, but instead uses the terms local/automatic storage and dynamic storage. – Michael Aaron Safyan Jul 30 '09 at 05:52
  • @Jim: Only if the object in the array is POD. If it is an object with a constructor then all objects have to be default constructed on allocation (which may not be what you want). With std::vector you can explicitly add code to build the objects correctly first time thus avoiding the extra cost of building an un-necessary object. – Martin York Jul 30 '09 at 07:11
  • @jalf That's wonderful that you can close yourself off to the world like that. +1 Jim. – mrduclaw Jul 30 '09 at 07:30
  • 1
    Yep, POD works beautifully here, which is the OP's example. With C++ objects, you would have to in-place construct them and explicitly destruct them. It's up to the programmer to decide whether the performance gains are worth it over the slight annoyance of explicit construction/destruction. – Jim Buck Jul 30 '09 at 15:04
  • Vector is NOT a correct solution ffs. – Enerccio Sep 01 '22 at 10:38