Variable length array confusion

Discussion in 'C Programming' started by dam_fool_2003@yahoo.com, Sep 29, 2003.

  1. Guest

    Hai,
    I studied that the array size is fixed. But I come across a word
    called "variable length array". Is it possible to change the array
    size? So I tried the following:
    #include<stdio.h>
    #include<stdlib.h>
    int main(void)
    {
    int y[3] = { 7, 9,10},i;
    for (;i<20;i++)
    printf("%d\n",y);
    return 0;
    }

    This is a wrong one and given me a runtime error.

    Then what is variable length array?

    So I tried the following:

    int main(void)
    {
    int y[3] = { 7, 9,10},i;
    for (;i<20;i++)
    {
    *y = malloc(sizeof *y);
    if(*y == NULL)
    exit(EXIT_FAILURE);
    else
    printf("%d size=%d\n",y,sizeof y);

    }
    return 0;
    }

    OUTPUT:

    589600 size=12
    9 size=12
    10 size=12
    0 size=12
    0 size=12
    0 size=12
    588632 size=12
    11912 size=12
    1 size=12
    589584 size=12
    593160 size=12
    …....
    …....
    ….....

    Even though it gave some warning and runtime error I can see the array
    size has changed since I used malloc and allocated with 3 * 4 (C array
    starts with zero) so the size = 12.

    1)Is my understanding of the above is correct?

    2)Is the above program behavior is undefined?

    Kindly help.
    , Sep 29, 2003
    #1
    1. Advertising

  2. <> schrieb im Newsbeitrag
    news:...
    > Hai,
    > I studied that the array size is fixed. But I come across a word
    > called "variable length array". Is it possible to change the array
    > size? So I tried the following:
    > #include<stdio.h>
    > #include<stdlib.h>
    > int main(void)
    > {
    > int y[3] = { 7, 9,10},i;
    > for (;i<20;i++)
    > printf("%d\n",y);
    > return 0;
    > }
    >
    > This is a wrong one and given me a runtime error.
    >
    > Then what is variable length array?
    >


    Here is an example
    (assuming you have no C99 compiler)

    #include <stdlib.h>
    #include <stdio.h>

    int main(void)
    {
    int i;
    void *tmp;
    int *y = malloc(20 * sizeof *y);

    if(y)
    {
    y[0] = 7;
    y[1] = 9;
    y[2] = 10;
    for(i = 3; i < 20; i++)
    {
    y = 0;
    }
    for(i = 0; i < 20; i++)
    {
    printf("%d ", y);
    }
    printf("\n");
    tmp = realloc(y, 25 * sizeof *y);
    if(tmp)
    {
    y = tmp;
    for(i = 3; i < 25; i++)
    {
    y = i;
    }
    for(i = 0; i < 25; i++)
    {
    printf("%d ", y);
    }
    printf("\n");
    }
    free(y);
    return EXIT_SUCCESS;
    }
    return EXIT_FAILURE;
    }

    Robert
    Robert Stankowic, Sep 29, 2003
    #2
    1. Advertising

  3. -berlin.de Guest

    wrote:
    > I studied that the array size is fixed. But I come across a word
    > called "variable length array". Is it possible to change the array
    > size? So I tried the following:
    > #include<stdio.h>
    > #include<stdlib.h>
    > int main(void)
    > {
    > int y[3] = { 7, 9,10},i;
    > for (;i<20;i++)


    You also need to initialize i, the way you use it here it will have
    some completely random value. Only static and global variables are
    initialized to 0.

    > printf("%d\n",y);
    > return 0;
    > }


    > This is a wrong one and given me a runtime error.


    Yes, because you're trying to access non-existent elements of the array
    'y'. Everything after y[2] does not belong to you.

    > Then what is variable length array?


    > So I tried the following:


    > int main(void)
    > {
    > int y[3] = { 7, 9,10},i;
    > for (;i<20;i++)


    Again, you need to initialize i, use e.g.


    for ( i = 0; i < 20; i++ )

    > {
    > *y = malloc(sizeof *y);


    Here you allocate memory for a single integer and assign the address
    you get back from malloc() to the first element of the array 'y',
    thereby implicitely converting the address to an integer (note that
    writing *y is the same as y[0] because y is always the same as
    *(y+i)). And, of course, that's nothing you should be doing and the
    compiler should emit a warning, at least if you have raised the
    warning level to something useful.

    > if(*y == NULL)
    > exit(EXIT_FAILURE);
    > else
    > printf("%d size=%d\n",y,sizeof y);


    Here you still run into the same problem as in your first program, you
    read past the last element of the 'y' array. Just having allocated some
    memory and assigned the address to the first element of the array doesn't
    change anything. And 'sizeof y' will always be 12 because that's the
    amount of memory taken by the array 'y' (you seem to run this on a
    machine where siezof(int) is 4). You can't change the size of 'y' by
    allocation, it's fixed the moment you compiled the program.

    > }
    > return 0;
    > }


    There are two things you seem to be confusing, variable length arrays
    and dynamically allocated arrays. Variable length arrays are a feature
    that has been introduced in (standard) C only with the new C99 standard
    and not all compilers support it yet. It means arrays of a length that
    hasn't been compiled in as a fixed number into the program but is only
    calculated during runtime. E.g. you can have a function like this

    void vla( int n )
    {
    int x[ n ];
    int i;

    for ( i = 0; i < n; i++ )
    x[ i ] = i;
    }

    This wasn't allowed with C89 (but some compilers did allow it as an
    extension, e.g. gcc) and which only a C99 compliant compiler must
    support.

    On the other had you have dynamically allocated arrays:

    void daa( int n )
    {
    int *x;
    int i;

    x = malloc( n * sizepf *x );
    if ( x == NULL )
    {
    fprintf( stderr, "Can't allocate memory\n" );
    exit( EXIT_FAILURE );
    }

    for ( i = 0; i < n; i++ )
    x[ i ] = i;

    free( x );
    }

    This is legal even with C89. Of course 'x' isn't a real array but just
    a pointer to some memory that can hold the number of integers you need.
    And in many places 'x' can be treated like a real array, but there are
    subtle differences, e.g. sizeof x is not the amount of memory it's
    pointing to but the size of a pointer. And, of course, you must free()
    the memory you allocated when you don't need it anymore.

    Regards, Jens
    --
    _ _____ _____
    | ||_ _||_ _| -berlin.de
    _ | | | | | |
    | |_| | | | | | http://www.physik.fu-berlin.de/~toerring
    \___/ens|_|homs|_|oerring
    -berlin.de, Sep 29, 2003
    #3
  4. On 29 Sep 2003 06:00:42 -0700, in comp.lang.c ,
    wrote:

    >Hai,
    > I studied that the array size is fixed. But I come across a word
    >called "variable length array".


    A variable length array is one whose length is a variable !!

    In old C, you had to declare variables with a constant as the length
    double foo[56];

    in new C you can declare them using a variable
    int bar = 56;
    double foo[bar];

    This is obviously handy if bar were a parameter to some function that
    needed a bar-sized array of doubles.

    >Is it possible to change the array
    >size?


    Once you create it, its fixed. (Note that malloc doesn't create
    arrays, although malloc'ed memory can be treated as an array to all
    intents and purposes, which of course begs the question "whats the
    point of VLAs then?")



    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
    Mark McIntyre, Sep 29, 2003
    #4
  5. Guest

    -berlin.de wrote in message news:<bl9dnm$98bn5$>...
    > wrote:
    > > I studied that the array size is fixed. But I come across a word
    > > called "variable length array". Is it possible to change the array
    > > size? So I tried the following:
    > > #include<stdio.h>
    > > #include<stdlib.h>
    > > int main(void)
    > > {
    > > int y[3] = { 7, 9,10},i;
    > > for (;i<20;i++)

    >
    > You also need to initialize i, the way you use it here it will have
    > some completely random value. Only static and global variables are
    > initialized to 0.
    >
    > > printf("%d\n",y);
    > > return 0;
    > > }

    >
    > > This is a wrong one and given me a runtime error.

    >
    > Yes, because you're trying to access non-existent elements of the array
    > 'y'. Everything after y[2] does not belong to you.
    >
    > > Then what is variable length array?

    >
    > > So I tried the following:

    >
    > > int main(void)
    > > {
    > > int y[3] = { 7, 9,10},i;
    > > for (;i<20;i++)

    >
    > Again, you need to initialize i, use e.g.
    >
    >
    > for ( i = 0; i < 20; i++ )
    >
    > > {
    > > *y = malloc(sizeof *y);

    >
    > Here you allocate memory for a single integer and assign the address
    > you get back from malloc() to the first element of the array 'y',
    > thereby implicitely converting the address to an integer (note that
    > writing *y is the same as y[0] because y is always the same as
    > *(y+i)). And, of course, that's nothing you should be doing and the
    > compiler should emit a warning, at least if you have raised the
    > warning level to something useful.

    ^^^^^^^^^^^^^^^

    Yes , gcc –Wall –o temp temp.c
    Gives me warning about the assignment.




    >
    > > if(*y == NULL)
    > > exit(EXIT_FAILURE);
    > > else
    > > printf("%d size=%d\n",y,sizeof y);

    >
    > Here you still run into the same problem as in your first program, you
    > read past the last element of the 'y' array. Just having allocated some
    > memory and assigned the address to the first element of the array doesn't
    > change anything. And 'sizeof y' will always be 12 because that's the
    > amount of memory taken by the array 'y' (you seem to run this on a
    > machine where siezof(int) is 4). You can't change the size of 'y' by
    > allocation, it's fixed the moment you compiled the program.
    >
    > > }
    > > return 0;
    > > }

    >
    > There are two things you seem to be confusing, variable length arrays
    > and dynamically allocated arrays. Variable length arrays are a feature
    > that has been introduced in (standard) C only with the new C99 standard
    > and not all compilers support it yet. It means arrays of a length that
    > hasn't been compiled in as a fixed number into the program but is only
    > calculated during runtime. E.g. you can have a function like this
    >
    > void vla( int n )
    > {
    > int x[ n ];
    > int i;
    >
    > for ( i = 0; i < n; i++ )
    > x[ i ] = i;
    > }
    >
    > This wasn't allowed with C89 (but some compilers did allow it as an
    > extension, e.g. gcc) and which only a C99 compliant compiler must
    > support.
    >
    > On the other had you have dynamically allocated arrays:
    >
    > void daa( int n )
    > {
    > int *x;
    > int i;
    >
    > x = malloc( n * sizepf *x );
    > if ( x == NULL )
    > {
    > fprintf( stderr, "Can't allocate memory\n" );
    > exit( EXIT_FAILURE );
    > }
    >
    > for ( i = 0; i < n; i++ )
    > x[ i ] = i;
    >
    > free( x );
    > }


    But how can we allocate a dynimic mem for an array
    In the code above it is *x but what can we do if x is decleared as a array?




    > This is legal even with C89. Of course 'x' isn't a real array but just
    > a pointer to some memory that can hold the number of integers you need.
    > And in many places 'x' can be treated like a real array, but there are
    > subtle differences, e.g. sizeof x is not the amount of memory it's
    > pointing to but the size of a pointer. And, of course, you must free()
    > the memory you allocated when you don't need it anymore.
    >
    > Regards, Jens


    Thanks for all the answers
    , Oct 1, 2003
    #5
  6. -berlin.de Guest

    wrote:
    > -berlin.de wrote in message news:<bl9dnm$98bn5$>...
    >> On the other had you have dynamically allocated arrays:
    >>
    >> void daa( int n )
    >> {
    >> int *x;
    >> int i;
    >>
    >> x = malloc( n * sizepf *x );
    >> if ( x == NULL )
    >> {
    >> fprintf( stderr, "Can't allocate memory\n" );
    >> exit( EXIT_FAILURE );
    >> }
    >>
    >> for ( i = 0; i < n; i++ )
    >> x[ i ] = i;
    >>
    >> free( x );
    >> }


    > But how can we allocate a dynimic mem for an array
    > In the code above it is *x but what can we do if x is decleared as a array?


    You can't change the length of an array once you have created it. If
    you need dynamically resizeable arrays you must work with pointers and
    use malloc()/realloc() to change the amount of memory they point to.
    If you look up how other languages implement arrays of non-fixed
    length (e.g. in Perl) you will find that they often are written in C
    and actually use malloc()/realloc() to achieve this effect.

    Regards, Jens
    --
    _ _____ _____
    | ||_ _||_ _| -berlin.de
    _ | | | | | |
    | |_| | | | | | http://www.physik.fu-berlin.de/~toerring
    \___/ens|_|homs|_|oerring
    -berlin.de, Oct 3, 2003
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mitchua
    Replies:
    5
    Views:
    2,715
    Eric J. Roode
    Jul 17, 2003
  2. Adam Warner

    Flexible array member + variable length array

    Adam Warner, Feb 3, 2005, in forum: C Programming
    Replies:
    10
    Views:
    784
    S.Tobias
    Feb 10, 2005
  3. Mark Anderson

    checkbox.length confusion

    Mark Anderson, Oct 21, 2003, in forum: Javascript
    Replies:
    6
    Views:
    92
    Mark Anderson
    Oct 22, 2003
  4. Tom
    Replies:
    3
    Views:
    198
    salsablr
    Dec 20, 2004
  5. Tuan  Bui
    Replies:
    14
    Views:
    462
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page