init array with instance - C

This is a discussion on init array with instance - C ; Hello there, I want to init my Test-Object with an initial value, but it doesn't work. What's wrong or how can it be done? #import <objc/Object.h> @interface Test: Object { int L; int array[L]; } -(Test *) initWith: (int) i; ...

+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 15

init array with instance

  1. Default init array with instance

    Hello there,

    I want to init my Test-Object with an initial value, but it doesn't work.
    What's wrong or how can it be done?

    #import <objc/Object.h>

    @interface Test: Object

    {
    int L;
    int array[L];
    }

    -(Test *) initWith: (int) i;

    @end

    @implementation Test;

    -(Test *) initWith: (int) i
    {
    L = i;

    self = [super init];
    return self;
    }

    @end

    int main()
    {
    Test *objekt = [[Test alloc] initWith: 100];
    return 0;
    }


  2. Default Re: init array with instance

    In article <e78gvv$s85$1@online.de>,
    Jonathan Groß <pge03cnx@studserv.uni-leipzig.de> wrote:

    > I want to init my Test-Object with an initial value, but it doesn't work.
    > What's wrong or how can it be done?
    >
    > -(Test *) initWith: (int) i
    > {
    > L = i;
    >
    > self = [super init];
    > return self;
    > }
    >


    the first line of the above function is shorthand for:

    self->L = i;

    so, it won't function correctly if it is before the next line.

    The fix is to reorder the two lines:

    self = [super init];
    L = i;

  3. Default Re: init array with instance

    In article <e78gvv$s85$1@online.de>,
    Jonathan Groß <pge03cnx@studserv.uni-leipzig.de> wrote:
    >Hello there,
    >
    >I want to init my Test-Object with an initial value, but it doesn't work.
    >What's wrong or how can it be done?
    >
    >#import <objc/Object.h>
    >
    >@interface Test: Object
    >
    >{
    > int L;
    > int array[L];
    >}


    if your goal is to allocate an array of 'L' elements, the above will not
    work, as 'L' is not known at compile time.

    You will need to alocate the array yourself. So, rather than declaring
    'int array[L]' as an instance variable, you need to declare an instance
    variable that is a suitable pointer, and then allocate a suitably large
    block of memory and assign it to that pointer:

    @interface Test : Object {
    int L;
    int *array;
    }
    >
    >@end
    >
    >@implementation Test;
    >


    -(Test *) initWith: (int) i
    {
    if ((self = [super init]) != nil) {
    L = i;
    array = (int *)malloc(L * sizeof(int));
    }
    return self;
    }

    >@end
    >
    >int main()
    >{
    > Test *objekt = [[Test alloc] initWith: 100];
    > return 0;
    >}


    Best wishes,

    // Christian Brunschen


  4. Default Re: init array with instance

    On 20/6/06 16:30, Christian Brunschen wrote:
    > In article <e78gvv$s85$1@online.de>,
    > Jonathan Groß <pge03cnx@studserv.uni-leipzig.de> wrote:
    >> Hello there,
    >>
    >> I want to init my Test-Object with an initial value, but it doesn't work.
    >> What's wrong or how can it be done?
    >>
    >> #import <objc/Object.h>
    >>
    >> @interface Test: Object
    >>
    >> {
    >> int L;
    >> int array[L];
    >> }

    >
    > if your goal is to allocate an array of 'L' elements, the above will not
    > work, as 'L' is not known at compile time.
    >


    Out of pedantry, if the C in Objective-C is C99 then you *can* declare a
    variable-length array. However, you still can't use L because the value
    of L isn't known at +alloc time. ObjC probably shouldn't support
    variable-length arrays anyway, even under ObjC99, because you
    effectively break the ability to subclass if you do it. So your
    solution which I removed was still the right one :-)

  5. Default Re: init array with instance

    Graham J Lee <uk.ac.ox.physics.teaching@leeg.invalid> wrote:
    > On 20/6/06 16:30, Christian Brunschen wrote:
    >> In article <e78gvv$s85$1@online.de>,
    >> Jonathan Gro? <pge03cnx@studserv.uni-leipzig.de> wrote:
    >>> Hello there,
    >>>
    >>> I want to init my Test-Object with an initial value, but it doesn't work.
    >>> What's wrong or how can it be done?
    >>>
    >>> #import <objc/Object.h>
    >>>
    >>> @interface Test: Object
    >>>
    >>> {
    >>> int L;
    >>> int array[L];
    >>> }

    >>
    >> if your goal is to allocate an array of 'L' elements, the above will not
    >> work, as 'L' is not known at compile time.

    >
    > Out of pedantry, if the C in Objective-C is C99 then you *can* declare a
    > variable-length array. However, you still can't use L because the value
    > of L isn't known at +alloc time. ObjC probably shouldn't support
    > variable-length arrays anyway, even under ObjC99, because you
    > effectively break the ability to subclass if you do it. So your
    > solution which I removed was still the right one :-)


    C99 variable-length arrays only work for local variables, not for struct
    (and therefore class) members. If you think about it, there are no
    non-constant values that would work, because the size of types has to be
    known at compile time, but the size of a particular variable doesn't.

    Using malloc/free is definitely the right way to go in this case. I
    recommend it even for local variables, because variable-length arrays use
    horrible stack mojo which is prone to breaking when your size becomes "too
    large". It's basically a friendly face around alloca(), and C programmers
    who know about it usually have a healthy respect and fear for alloca().

    --
    Michael Ash
    Rogue Amoeba Software

  6. Default Re: init array with instance

    On 2006-06-20 17:30:34 +0200, cb@festis.df.lth.se (Christian Brunschen) said:

    > In article <e78gvv$s85$1@online.de>,
    > Jonathan Groß <pge03cnx@studserv.uni-leipzig.de> wrote:
    >> Hello there,
    >>
    >> I want to init my Test-Object with an initial value, but it doesn't work.
    >> What's wrong or how can it be done?
    >>
    >> #import <objc/Object.h>
    >>
    >> @interface Test: Object
    >>
    >> {
    >> int L;
    >> int array[L];
    >> }

    >
    > if your goal is to allocate an array of 'L' elements, the above will
    > not work, as 'L' is not known at compile time.
    >
    >
    > @interface Test : Object {
    > int L;
    > int *array;
    > }
    > -(Test *) initWith: (int) i
    > {
    > if ((self = [super init]) != nil) {
    > L = i;
    > array = (int *)malloc(L * sizeof(int));
    > }
    > return self;
    > }


    Thanks. This did work!


  7. Default Re: init array with instance

    On 20/6/06 20:01, Michael Ash wrote:
    > Graham J Lee <uk.ac.ox.physics.teaching@leeg.invalid> wrote:
    >> On 20/6/06 16:30, Christian Brunschen wrote:
    >>> In article <e78gvv$s85$1@online.de>,
    >>> Jonathan Gro? <pge03cnx@studserv.uni-leipzig.de> wrote:
    >>>> Hello there,
    >>>>
    >>>> I want to init my Test-Object with an initial value, but it doesn't work.
    >>>> What's wrong or how can it be done?
    >>>>
    >>>> #import <objc/Object.h>
    >>>>
    >>>> @interface Test: Object
    >>>>
    >>>> {
    >>>> int L;
    >>>> int array[L];
    >>>> }
    >>> if your goal is to allocate an array of 'L' elements, the above will not
    >>> work, as 'L' is not known at compile time.

    >> Out of pedantry, if the C in Objective-C is C99 then you *can* declare a
    >> variable-length array. However, you still can't use L because the value
    >> of L isn't known at +alloc time. ObjC probably shouldn't support
    >> variable-length arrays anyway, even under ObjC99, because you
    >> effectively break the ability to subclass if you do it. So your
    >> solution which I removed was still the right one :-)

    >
    > C99 variable-length arrays only work for local variables, not for struct
    > (and therefore class) members. If you think about it, there are no
    > non-constant values that would work, because the size of types has to be
    > known at compile time, but the size of a particular variable doesn't.


    Yup, you're right about C99, and I was wrong and misleading. I was
    thinking of flexible arrays, which GNU C (at least) supports as long as
    they're the last element of the struct (effectively by malloc()ing past
    the end of the struct). ObjC *doesn't* allow them, because it would be
    a right mess trying to deal with that and subclassing would effectively
    become impossible.

  8. Default Re: init array with instance

    Jonathan Groß wrote:
    > On 2006-06-20 17:30:34 +0200, cb@festis.df.lth.se (Christian Brunschen)
    > said:
    >
    >> In article <e78gvv$s85$1@online.de>,
    >> Jonathan Groß <pge03cnx@studserv.uni-leipzig.de> wrote:
    >>
    >>> Hello there,
    >>>
    >>> I want to init my Test-Object with an initial value, but it doesn't
    >>> work.
    >>> What's wrong or how can it be done?
    >>>
    >>> #import <objc/Object.h>
    >>>
    >>> @interface Test: Object
    >>>
    >>> {
    >>> int L;
    >>> int array[L];
    >>> }

    >>
    >>
    >> if your goal is to allocate an array of 'L' elements, the above will
    >> not work, as 'L' is not known at compile time.
    >>
    >>
    >> @interface Test : Object {
    >> int L;
    >> int *array;
    >> }
    >> -(Test *) initWith: (int) i
    >> {
    >> if ((self = [super init]) != nil) {
    >> L = i;
    >> array = (int *)malloc(L * sizeof(int));
    >> }
    >> return self;
    >> }

    >
    >
    > Thanks. This did work!


    only if malloc succeeded, otherwise you will get a crash next time you
    access an element. This should be better:

    -(Test *) initWith: (int) i
    {
    self = [super init];
    if (!self) {
    // process initialization error...
    // exit or throw exception
    }

    L = 0;
    array = malloc(i * sizeof(*array));
    if (!array) {
    // process allocation error...
    // exit or throw exception
    }
    L = i;

    return self;
    }

    a+, ld.

  9. Default Re: init array with instance

    Graham J Lee <uk.ac.ox.physics.teaching@leeg.invalid> wrote:
    >
    > Yup, you're right about C99, and I was wrong and misleading. I was
    > thinking of flexible arrays, which GNU C (at least) supports as long as
    > they're the last element of the struct (effectively by malloc()ing past
    > the end of the struct).


    Note that C "allows" these as well, although GNU C has the added
    convenience of allowing you to specify a 0-length array, whereas normal C
    forces you to put in a 1 and then play games with your sizes to take it
    into account.

    > ObjC *doesn't* allow them, because it would be
    > a right mess trying to deal with that and subclassing would effectively
    > become impossible.


    If you aren't subclassed then you can do the same thing as with structs.
    Making sure extra memory gets allocated can be tricky, though, since it's
    usually the root object that takes care of that for you. But if you didn't
    mind being evil you could override +alloc and stick a variable-length
    array at the end of your class.

    --
    Michael Ash
    Rogue Amoeba Software

  10. Default Re: init array with instance

    Laurent Deniau <laurent.deniau@cern.ch> wrote:
    >
    > only if malloc succeeded, otherwise you will get a crash next time you
    > access an element. This should be better:
    >
    > -(Test *) initWith: (int) i
    > {
    > self = [super init];
    > if (!self) {
    > // process initialization error...
    > // exit or throw exception
    > }
    >
    > L = 0;
    > array = malloc(i * sizeof(*array));
    > if (!array) {
    > // process allocation error...
    > // exit or throw exception
    > }
    > L = i;
    >
    > return self;
    > }


    While technically this is very true and never a bad idea, I'll note that
    checking for allocation failures on UNIX is the exception rather than the
    rule, and explicit allocation failures are unlikely to happen anyway. Much
    more likely is that you'll get a pointer that isn't valid yet, and then
    the OS will hang or kill your process when you try to access it and the OS
    discovers it can't fulfill its promise. While it doesn't hurt to check for
    failure, it will only catch a small proportion of the problems.

    --
    Michael Ash
    Rogue Amoeba Software

+ Reply to Thread
Page 1 of 2 1 2 LastLast

Similar Threads

  1. converting arguments to an Array instance
    By Application Development in forum Javascript
    Replies: 5
    Last Post: 12-04-2007, 07:04 PM
  2. Replies: 3
    Last Post: 11-09-2007, 07:41 PM
  3. Making a vector init like and array
    By Application Development in forum c++
    Replies: 4
    Last Post: 09-12-2007, 07:04 AM
  4. array init in formula node
    By Application Development in forum labview
    Replies: 2
    Last Post: 07-25-2007, 11:40 AM
  5. How to identify myself in an instance array
    By Application Development in forum verilog
    Replies: 4
    Last Post: 03-16-2006, 01:36 AM