Search code examples
genericsheap-memoryinstantiationadastack-memory

Ada Generics: Stack vs Heap Clarification


So I have an assignment that says:

Please use generic instantiations of packages/classes. Space for each BMR (matrix) must be allocated in the system stack within the generic package/template, probably during generic instantiation! You specifically may not use "new,” “malloc,” or any other operator, which allocates space in the heap at runtime in any language. Clearly mark this section of your code with a highlighter! You must read all transactions and print all results within the generic package/template. The I/O routines must be passed as generic parameters

And unrelated code:

generic
    type subscript is (<>);     --range variable to be instantiated
    type myType is private;     --type variable to be intantiated
package genericArray is
    type userDefinedArray is array(subscript range <>) of myType;
end genericArray;

with ada.text_io;  use ada.text_io;
with genericArray;

procedure useGenericArray is
type month_name is (jan, feb, mar, apr, may, jun,
                    jul, aug, sep, oct, nov, dec);
type date is 
    record
        day: integer range 1..31;  month: month_name;  year: integer;
    end record;

type family is (mother, father, child1, child2, child3, child4);

package month_name_io is new ada.text_io.enumeration_io(month_name);
use month_name_io;

package IIO is new ada.text_io.integer_io(integer);
use IIO;

package createShotArrayType is new genericArray(family, date);
use createShotArrayType;

vaccine: userDefinedArray(family);

begin
    vaccine(child2).month := jan;
    vaccine(child2).day := 22;
    vaccine(child2).year := 1986;
    put("child2:    ");
    put(vaccine(child2).month);
    put(vaccine(child2).day);
    put(vaccine(child2).year);  new_line;
end useGenericArray;

Again, the code posted has nothing to do with the assignment, but my question is that, in the code posted, is space being allocated in the stack or the heap every time I use the word "new". Because my directions say NOT to use this word, but then it says to use generic instantiation which requires it I think. I would appreciate clarification!


Solution

  • The instructions say

    You specifically may not use "new,” “malloc,” or any other operator, which allocates space in the heap at runtime in any language.

    which clearly means you mustn’t do heap allocations (why they couldn’t say that first I don’t know; might have been clearer). And that comma after "operator" is misleading.

    Instantiating a generic typically happens at compile time; but even if you did

    Ada.Integer_IO.Get (N);
    declare
       package Inst is new Some_Generic (N);
    begin
       ...
    end;
    

    the instantiation doesn’t of itself involve heap allocation.

    You could write the generic so that the instantiation above allocates stack:

    generic
       J : Positive;
    package Some_Generic is
       type Arr is array (1 .. J) of Integer;
       A : Arr;    --  in a declare block, this ends up on the stack
    end Some_Generic;
    

    or even heap:

    generic
       J : Positive;
    package Some_Generic is
       type Arr is array (1 .. J) of Integer;
       type Arr_P is access Arr;
       P : Arr_P := new Arr;  --  always on the heap
    end Some_Generic;
    

    but that’s because of the code you wrote in the generic, not the syntax that requires you to use the word new to instantiate it.