Re allocating C array for more space - c

Im writing a program with a function add(a , i, n) which will add 'i' as an element to 'a', but if the array 'a' runs out of space, then I need to realloc more memory to the array. Im stuck here:
#include <stdlib.h>
#include <stdio.h>
int add(int* a, int i, int n);
int main(){
int n = 20;
int *a = (int*) malloc(n*sizeof(int));
int i;
for (i = 0; i < 100000; i++){
n = add(a, i, n);
printf("a[%d]=%d\n",i,(int)a[i]);
}
return 0;
}
int add(int *a, int i, int n){
if (i >= n){
n++;
int* b = (int*) realloc(a, n*sizeof(int));
a[i]=i;
return n;
}else{
}
}
Im not very experienced so please be gentle...

realloc tries to reallocate the given memory, but sometimes, it can't and gives you a new memory pointer.
It must be used like:
int *b;
b = realloc(a, <newsize>);
if (b) {
/* realloc succeded, `a` must no longer be used */
a = b;
/* now a can be used */
printf("ok\n");
} else {
/* realloc failed, `a` is still available, but it's size did not changed */
perror("realloc");
}
Now, you still have some trouble in your code:
The idea of function add() is to reallocate a when needed, but a is given by copy, so its value won't be changed in main.
#include <stdlib.h>
#include <stdio.h>
int add(int** a, int i, int n);
int main(){
int n = 20;
int *a = malloc(n*sizeof(int));
int i;
for (i = 0; i < 100000; i++) {
/* note how `a` is passed to `add` */
n = add(&a, i, n);
printf("a[%d]=%d\n",i,a[i]);
}
/* and finally free `a`*/
free(a);
return 0;
}
/* changed `a` type to make its new value visible in `main` */
int add(int **a, int i, int n){
if (i >= n){
/* want to write a[i], so size must be at least i+1*/
n = i+1;
/* realloc memory */
int *b = realloc(*a, n*sizeof(int));
/* check that `realloc` succeded */
if (!b) {
/* it failed!*/
perror("realloc");
exit(1);
}
/* store new memory address */
*a = b;
}
/* update memory */
(*a)[i]=i;
/* return new size */
return n;
}
Note: I removed malloc/realloc cast, see: Do I cast the result of malloc?

To have an automatically growing array in C you would normally need a helper function ensure_capacity to take care of the array reallocation.
The helper function would preferrably reallocate using 2x grow policy, so you have an amortized constant time of the append operation.
The code would look somewhatlike the below.
Note that the code is using the first 2 elements of the array to keep its capacity/size. You can use a struct of pointer + size instead, but you need to keep the two close two each other as otherwise the code won't be easy to read.
int* ensure_capacity(int* vec, int new_cap) {
if (vec == 0) {
vec = (int*) malloc(18 * sizeof(int));
vec [0] = 16;
vec [1] = 0;
} else {
int cap = vec[0];
if (cap < new_cap) {
do {
cap *= 2;
} while (cap < new_sz);
int* new_vec = (int*) realloc(vec, cap * sizeof(int));
if (new_vec != null) {
vec = new_vec;
vec[0] = cap;
} else {
// reallocation failed, handle the error
}
}
}
return vec;
}
And you would use it in your add() function like:
int* push_back(int* vec, int val) {
vec = ensure_capacity(vec, vec[1] + 1);
vec[vec[1]++] = val;
return vec;
}

Related

Where should I put free() in C?

I'm a bit new to C-programming and I can't seem to understand where should I free the int* array I initialized. I tried to put free(array) after I've got what I need but Valgrind still reports a memory leak and an invalid free at the location I proposed. Where should I put the free(array) call in this code?
Note: the actual code implementation is removed to make the code simpler while retaining the bug.
// C-language code (C99)
#include <stdio.h>
#include <stdlib.h>
int fib(int index, int *array, int initBlocks);
int processFib(int index);
int doubleStorage(int **array, int initialBlocks);
int main() {
int ans = processFib(10);
printf("ans = %d", ans);
return 0;
}
// initialises an array and calls the fib(...) function
int processFib(int index) {
int defaultInitBlocks = 10;
int *array = calloc(defaultInitBlocks, sizeof(int));
array[1] = 1;
array[2] = 1;
int ans = fib(index, array, defaultInitBlocks);
free(array); /* Valgrind says InvalidFree here ----------------------*/
return ans;
}
// doubles storage of array using realloc
int doubleStorage(int **array, int initialBlocks) {
int factor = 2;
int *temp = realloc(*array, factor * initialBlocks * sizeof(int));
/* Valgrind says the realloc here is a DefinitelyLost memory leak --------*/
if (!temp) {
free(*array);
return -1;
} else {
*array = temp;
for (int i = initialBlocks; i < factor * initialBlocks; i++) {
(*array)[i] = 0;
}
return factor * initialBlocks;
}
}
// doubles storage if 'index' is greater than array storage. Else, returns 1
int fib(int index, int *array, int initBlocks) {
if (index >= initBlocks) {
int newBlocks = doubleStorage(&array, initBlocks);
return fib(index, array, newBlocks);
}
return 1;
}
EDIT: SOLUTION MOVED TO ANSWERS
SOLUTION
A double pointer is now used in the fib() function which cleared the Valgrind warning (code below). Heads up to #WhozCraig for his comment.
int fib(int index, int **array, int initBlocks) {
if (index >= initBlocks) {
int newBlocks = doubleStorage(array, initBlocks);
return fib(index, array, newBlocks);
}
if (array[index] > 0) {
return (*array)[index];
} else {
(*array)[index] = fib(index - 1, array, initBlocks)
+ fib(index - 2, array, initBlocks);
return (*array)[index];
}
}

Function to resize array not working [C]

This is a program for studying purposes.
I'm trying to increment an array size while the program is running, until its size is equal to 12. But i'm getting an error and i don't know why. Will appreciate your help.
#include <stdlib.h>
#include <stdio.h>
void incrementSize(int **arr, int *currentSize);
void swap(int **a, int **b);
void main() {
int i = 0,
size = 3;
int *array = (int*)malloc(size * sizeof(int));
while (size < 12) {
if (i == size) //If the logical size is equal to the physical size increment the size of the array.
incrementSize(&array, &size);
array[i] = i + 1;
i++;
}
for (int j = 0; j < size; j++) //Prints the array
printf("%d ", array[j]);
printf("\n");
}
I wrote this function to increment the size of a given array and returns the new size.
void incrementSize(int **arr, int *currentSize)
{
int newSize = 2 * (*currentSize);
int *tmpArr = realloc(*arr, newSize * sizeof(int));
if (!tmpArr)
//If the allocation didn't work
{
printf("ERROR. Memory reallocation failed!");
free(tmpArr);
}
else
//If it worked swap the addresses of "tmpArr" and "arr" and then free "tmpArr"
{
swap(arr, &tmpArr);
free(tmpArr);
*currentSize *= 2;
}
}
and also wrote this function to swap the addresses of two given arrays
void swap(int **a, int **b)
{
int* tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
realloc actually frees storage pointed by given pointer.
If there is not enough memory, the old memory block is not freed and
null pointer is returned.
If argument is NULL, the behavior is the same as calling malloc(new_size).
Code you wrote would free already freed memory.

Increase dynamic array size with a function; free error, invalid next size (fast)

I need to create a dynamic array and put five number, after there is another input which is how much I have to increase the array size.
When all input are ended I am going to increase the array size and put numbers inside.
everything works but free return me this error: "free(): invalid next size (fast): 0x00000..."
I think there are errors inside "extend" function
void extend(int *V, int n, int s)
{
int *pt;
pt = realloc(V, n*sizeof(int));
int i;
pt[5]=s;
for(i=6;i<(5+n);i++)
pt[i] = pt[i-1]*2;
}
int main()
{
int *v;
int n,i, sum;
sum = 0;
v = malloc(sizeof(int)*5);
for(i=0;i<5;i++)
{
scanf("%d", &v[i]);
sum+=v[i];
}
scanf("%d", &n);
extend(v,n,sum);
for(i=0;i<(5+n);i++)
printf("%d\n", v[i]);
free(v);
return 0;
}
The function does not change the original variable v. It should be defined at least like
void extend(int **V, int n, int s)
{
int *pt;
pt = realloc(*V, n*sizeof(int));
if ( pt )
{
int i;
pt[5]=s;
for(i=6; i < n; i++)
pt[i] = pt[i-1]*2;
*V = pt;
}
}
Or
int extend(int **V, int n, int s)
{
int *pt;
pt = realloc(*V, n*sizeof(int));
int success = pt != NULL;
if ( success )
{
int i;
pt[5]=s;
for(i=6; i < n; i++)
pt[i] = pt[i-1]*2;
*V = pt;
}
return success;
}
And the function should be called lije
extend( &v,n,sum);
Take into account that the function is unsafe because in general n can be less than or equal to 5. And this statement
for(i=6;i<(5+n);i++)
^^^^
can result in undefined behavior.
Or the function shall allocate n + 5 elements. For example
pt = realloc(*V, ( n + 5 )*sizeof(int));
^^^^^^^^
Also the using of this magic number 5 is unclear and does not make sense.
Well, in function extend:
You are allocating pt to a memory block of n entries
You are attempting to access pt at indexes beyond n-1
More specifically, with:
pt = realloc(V, n*sizeof(int));
for (i=6; i<(5+n); i++)
pt[i] = ...
You are performing illegal memory-access operations on:
pt[n]
pt[n+1]
pt[n+2]
pt[n+3]
pt[n+4]
The realloc returns a pointer to the new memory block but you do not return that to the caller. Instead v in main, is the same v that was before the call but now invalid and which causes your error no doubt, easiest is to return pt instead:
int* extend(int *V, int n, int s)
{
int *pt;
pt = realloc(V, n*sizeof(int));
int i;
pt[5]=s;
for(i=6;i<(5+n);i++)
pt[i] = pt[i-1]*2;
return pt;
}
...
v = extend(v,n,sum);
another thing that is not correct is your initialization of the new elements, n should contain the number of new elements plus any old since you want the allocated the block to be bigger. better to give old and new number of elements to it:
int* extend(int *V, int oldNumber, int newNumber, int s)
{
int *pt = realloc(V, newNumber*sizeof(int));
int i;
if (pt==NULL)
{
fprintf(stderr,"Out of memory\n");
return V;
}
pt[oldNumber]=s;
// now you can initialize the rest of the array
for(i=oldNumber+1;i<newNumber;i++)
pt[i] = pt[i-1]*2;
return pt;
}
...
v = extend(v,5,n,sum);
Grow an array like this
int capacity = 10; // don't start off as tiny
ENTRY *array = malloc(capacity * sizeof(ENTRY));
int N = 0; //number of entries.
To add
int addentry(ENTRY *entry)
{
ENTRY *temp;
if(N >= capacity)
{
temp = realloc(array, (capacity + capacity/2) * sizeof(ENTRY));
if(!temp)
goto out_of_memory;
array = temp;
capacity = capacity + capacity/2;
}
array[N] = *entry;
N++;
return 0;
out_of_memory:
//always a problem, maybe terminate program here
// as it is, just shunt up
return -1;
}
You need the temp because realloc returns 0 on failure but keeps
the argument intact, so you need to keep array to destroy it
gracefully. Grow by about 1.5, doubling is too aggressive and
reallocating on every call is too expensive.

realloc(): invalid next size and double free

As a homework, I'm supposed to create 2 functions that enable you to push and pop elements to an array that acts as a queue. We're supposed to do this dynamically allocating memory. My program is almost working, but sometimes when adding and removing too many elements, I get errors like "realloc(): invalid next size", double free (when I've only called the free function once) and some of the elements in the beginning of the queue are set to 0. For instance, if I first add 100 elements, then remove 90 and try to add another 20, I get "free(): invalid next size (fast): 0x0000000001ea6010".
What am I doing wrong here?
According to suggestions below I changed my functions to take a double pointer as an input for the array. That, however, now gives me a Segmentation fault - which means now I don't know what to look for at all...
#include <stdio.h>
#include <stdlib.h>
void enqueue(int **arr, int* lastElementIdx, size_t* totalElements, int element) {
if (*lastElementIdx >= *totalElements) { // check if memorry is sufficient, otherwise double
*totalElements *= 2;
int* temp = realloc(arr, (*totalElements * sizeof(int)));
if (temp == NULL) { // just in case realloc fails
printf("Allocation error\n");
} else {
*arr = temp;
}
}
if (*lastElementIdx <= *totalElements) {
*lastElementIdx += 1; // once everything is done: add element
*arr[*lastElementIdx] = element;
}
}
int dequeue(int **arr, int* lastElementIdx, size_t* totalElements) {
if (*lastElementIdx > -1) { // if queue is not empty...
int deleted = *arr[0]; // save deleted value first (in case it's still needed)
for (int i = 0; i <= *lastElementIdx; i++) { // shift all elements
*arr[i] = *arr[i + 1];
}
*lastElementIdx -= 1; // index is now decreased by 1
if (((*totalElements / 2) >= 10) && ((*lastElementIdx + 1) < (*totalElements / 2))) { // cut memory in half if not needed
*totalElements /= 2;
*arr = realloc(arr, (*totalElements * sizeof(int)));
int* temp = realloc(arr, (*totalElements * sizeof(int)));
if (temp == NULL) { // in case realloc fails
printf("Allocation error\n");
return 0;
} else {
*arr = temp;
}
}
return deleted;
} else { // if queue is empty, print that there's nothing to dequeue
printf("There are no elements inside the queue\n");
return 0;
}
}
void printQueue(int arr[], int lastElementIdx) {
for (int i = 0; i <= lastElementIdx; i++) { // print entire queue
printf("[%d] = %d\n", i, arr[i]);
}
printf("\n");
}
int main (void) {
size_t totalElements = 10; // number of needed elements at the time
int lastElementIdx = -1; // index of last element in queue at the time
int *arr = calloc(totalElements, sizeof(int));
int **arrpointer = &arr;
for (int i = 1; i < 101; i++) {
enqueue(arrpointer, &lastElementIdx, &totalElements, i);
}
printQueue(arr, lastElementIdx);
for (int i = 0; i < 90; i++) {
dequeue(arrpointer, &lastElementIdx, &totalElements);
}
printQueue(arr, lastElementIdx);
for (int i = 1; i < 21; i++) {
enqueue(arrpointer, &lastElementIdx, &totalElements, i);
}
printQueue(arr, lastElementIdx);
free(arr);
return EXIT_SUCCESS;
}
When you expand or contract the storage for your queue, you need to provide a pointer to the storage back to the caller. This is because realloc() does not necessarily resize a memory block in-place -- it may create a new, differently sized block elsewhere. It is permitted to do so even when it resizes to a smaller block, not only when it resizes to a larger one.
Your usage of variable temp gives the appearance that you are aware of this issue, but as #DerkHermann first observed, you mishandle the resulting pointer. Perhaps you meant to write something along the lines of
arr = temp;
instead. Even that is not sufficient, however. C has only pass-by-value, so if you modify the value of function parameter arr, that modification is visible only in the function (which receives in arr a copy of the value the caller passes). In the event that realloc() allocates a new block, that leaves the caller with an invalid pointer.
If you want your enqueue() and dequeue() functions to be able to resize the storage for the queue, then you must pass the pointer to that storage indirectly. The most straightforward way of doing that, given where you are now, would be to pass a double pointer, so that you can modify its referrent:
void enqueue(int **arr, int* lastElementIdx, size_t* totalElements, int element) {
/* ... */
*arr = temp;
/* ... */
}
Observe, however, that you are passing three separate pointers that among them represent the state of the queue. It would be cleaner to create a struct type that combines those details in one package, and to pass a pointer to an object of that type:
struct queue {
int *arr;
size_t capacity;
size_t last_element_index;
};
void enqueue(struct queue *queue, int element) {
/* ... */
queue->arr = temp;
/* ... */
}
Maybe it's not the only problem, but at least the following line does not what you seem to expect:
*temp = *arr;
It looks as if you want to replace arr with the result of the realloc, delivering it back to the calling function (as with your other inout arguments). But, arr is not an inout argument: It is an array of integers, not a pointer to an array of integers. What you are actually doing with your above line of code is to copy the first element of arr to the newly allocated memory range. That newly allocated memory range temp, then, is nevertheless forgotten, creating a memory leak.
Adding a double pointer to reallocate the space in the right places, changing the comparing function with size_t totalElements and fixing a few additional mistakes finally did the trick.
#include <stdio.h>
#include <stdlib.h>
void enqueue(int **arr, int* lastElementIdx, size_t* totalElements, int element) {
if (*lastElementIdx + 1 >= (int)(*totalElements) - 1) { // check if memorry is sufficient, otherwise double
*totalElements *= 2;
int* temp = realloc(*arr, (*totalElements * sizeof(int)));
if (temp == NULL) { // just in case realloc fails
printf("Allocation error\n");
} else {
*arr = temp;
}
}
if (*lastElementIdx + 1 <= (int)(*totalElements) - 1) {
*lastElementIdx += 1; // once everything is done and if there is now enough space: add element
(*arr)[*lastElementIdx] = element;
}
}
int dequeue(int **arr, int* lastElementIdx, size_t* totalElements) {
if (*lastElementIdx > -1) { // if queue is not empty...
int deleted = (*arr)[0]; // save deleted value first (in case it's still needed)
for (int i = 0; i <= *lastElementIdx; i++) { // shift all elements
(*arr)[i] = (*arr)[i + 1];
}
*lastElementIdx -= 1; // index is now decreased by 1
if (((*totalElements / 2) >= 10) && ((*lastElementIdx + 1) < (*totalElements / 2))) { // cut memory in half if not needed
*totalElements /= 2;
int* temp = realloc(*arr, (*totalElements * sizeof(int)));
if (temp == NULL) { // in case realloc fails
printf("Allocation error\n");
return 0;
} else {
*arr = temp;
}
}
return deleted;
} else { // if queue is empty, print that there's nothing to dequeue
printf("There are no elements inside the queue\n");
return 0;
}
}
void printQueue(int arr[], int lastElementIdx) {
for (int i = 0; i <= lastElementIdx; i++) { // print entire queue
printf("[%d] = %d\n", i, arr[i]);
}
printf("\n");
}
int main (void) {
size_t totalElements = 10; // number of needed elements at the time
int lastElementIdx = -1; // index of last element in queue at the time
int *arr = calloc(totalElements, sizeof(int));
int **arrpointer = &arr;
for (int i = 1; i < 101; i++) {
enqueue(arrpointer, &lastElementIdx, &totalElements, i);
}
printQueue(arr, lastElementIdx);
for (int i = 0; i < 102; i++) {
dequeue(arrpointer, &lastElementIdx, &totalElements);
}
printQueue(arr, lastElementIdx);
for (int i = 1; i < 21; i++) {
enqueue(arrpointer, &lastElementIdx, &totalElements, i);
}
printQueue(arr, lastElementIdx);
free(arr);
return EXIT_SUCCESS;
}

An array that increases in size as a loop continues C

I'm trying to generate an array that increases in size as a while loop iterates. I know a pointer has something to do with the solution. Please look at the code below.
#include <stdio.h>
int main () {
int x = 0;
int *F = malloc(sizeof(int)); //I want F to start out as :-
F[0] = 1; // 1 by 1
F[1] = 2; // 1 by 2 such that it increases in size when assigned
int now = 2;
int evenSum = 2;
while (x <= 40000) {
F[now] = F[now-1] + F[now-2];
x = F[now];
if (F[now] % 2)
{
evenSum += F[now];
}
++now;
}
printf("The outcome is %d\n", evenSum);
//free(F);
// Yes this is problem 2 of euler challenge, i already got a working static model
}
Many Thanks in Advance
EDIT
What I'm actually looking for is the sum of all the even fib's up to a cut off limit of 40M. I could (what i did first time) sum the even numbers as i encounter them during the fib sequence. This meant i did not keep a array of some arbitary size. The purpose of this post is to create a growing memory that just keeps on consuming memory until it gets to the answer.
The following is the code I got from the brilliant answer that was given.
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
struct vector {
size_t size;
int *data;
};
void vector_resize(struct vector *vector, size_t size) {
if (vector->size >= size)
return;
while (vector->size < size)
vector->size *= 2;
vector->data = realloc(vector->data, sizeof(int) * vector->size);
assert(vector->data != NULL);
}
struct vector * vector_init() {
struct vector *vector = malloc(sizeof(*vector));
vector->size = 4;
vector->data = malloc(vector->size * sizeof(int));
return vector;
}
void vector_free(struct vector *vector) {
free(vector->data);
free(vector);
}
void vector_put(struct vector *vector, size_t index, int data) {
vector_resize(vector, index+1);
vector->data[index] = data;;
}
int vector_get(struct vector *vector, size_t index) {
vector_resize(vector, index+1);
return vector->data[index];
}
int main() {
struct vector *vector = vector_init();
int fibNow = 0;
int now = 2;
vector_put(vector, 0, 1);
vector_put(vector, 1, 2);
int evenSum = 2;
while (fibNow <= 4000000) {
fibNow = vector_get(vector, (now-1)) + vector_get(vector, (now-2));
vector_put(vector, now, fibNow);
if (fibNow % 2 == 0) {
evenSum += fibNow;
}
++now;
}
printf("The outcome is %d\n", evenSum);
// vector_put(vector, 0, 5);
// vector_put(vector, 9, 2);
// int i;
// for (i=0; i<10; ++i)
// printf("index 0: %d\n", vector_get(vector, i));
vector_free(vector);
}
So, In C we aren't allowed to overload the operator[]. But we could still create an object that functions like your request:
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
struct vector {
size_t size;
int *data;
};
void vector_resize(struct vector *vector, size_t size) {
if (vector->size >= size)
return;
while (vector->size < size)
vector->size *= 2;
vector->data = realloc(vector->data, sizeof(int) * vector->size);
assert(vector->data != NULL);
}
struct vector * vector_init() {
struct vector *vector = malloc(sizeof(*vector));
vector->size = 4;
vector->data = malloc(vector->size * sizeof(int));
return vector;
}
void vector_free(struct vector *vector) {
free(vector->data);
free(vector);
}
void vector_put(struct vector *vector, size_t index, int data) {
vector_resize(vector, index+1);
vector->data[index] = data;;
}
int vector_get(struct vector *vector, size_t index) {
vector_resize(vector, index+1);
return vector->data[index];
}
int main() {
struct vector *vector = vector_init();
vector_put(vector, 0, 5);
vector_put(vector, 9, 2);
for (int i=0; i<10; ++i)
printf("index 0: %d\n", vector_get(vector, i));
vector_free(vector);
}
Additionally, it's fun to look at a C++ version of what this could be. C++ makes this look far more like your original code, because we can overload operator[] for arbitrary objects.
#include <cstdio>
#include <vector>
template <typename T>
class auto_growing_vector {
private:
std::vector<T> data;
public:
T & operator[](size_t index) {
if (index >= data.size())
data.resize(index + 1);
return data[index];
}
};
int main() {
auto_growing_vector<int> vector;
vector[0] = 5;
vector[9] = 2;
for (int i=0; i<10; ++i)
printf("index 0: %d\n", vector[i]);
}
In general, realloc should do the trick for you. Example (this is just a snippet - you will need to do the rest yourself):
int *F;
F = malloc(2 * sizeof *F); // note you have to start with 2 elements for your code, not 1
F[0] = 1;
F[1] = 2;
// when you know you need to increase the size of F:
temp = realloc(F, n * sizeof *F); // where n is the new size in elements
if(temp != NULL) F = temp; // note that the block may have moved to a new place!
else {
printf("unable to grow the array to %d elements!\n", n);
free(F);
exit(0);
}
Of course for this problem you don't need to keep all the Fibonacci numbers - just the last two. This actually suggests a much simpler code. Let me start if for you, and see if you can finish it (since you are doing the Euler problems, which are all about figuring it out for yourself):
int first = 1;
int second = 1; // usually you start with 1,1,2,3,...
int temp, current;
int count;
int N = 4000; // where we stop
for(count = 2; count < N; count ++) {
current = first + second;
first = second;
second = current;
}
If you look closely, you can get even more efficient that this (hint, you really only need to keep one older value, not two...)
Reading the comments, if you want all the numbers in memory, you should just allocate enough space from the outset:
F = malloc(4000 * sizeof *F);
and no further manipulations are needed. Make sure your last index is 3999 in that case (since arrays are zero indexed).
I One way would be to use 2D array int[n][n], whith a lot of unused space
II Easier way would be to expend array size in every iteration by realocate function.
Just in that case, either:
a) every element of the original array would be a pointer to a new array of length i (i beeing iteration number), you would then realocate the original array to make size for new pointer, then allocate i*sizeof(int) of new memory for that new array that pointer would point to.
b) You would make linearized traingular matrix in which the original array will hold just numbers, not pointers. In every iteration you would expand it's size for i new elements. Linearized trangular matrix is a onedimensional array of numbers in which data is saved like this:
ordinary matrix: (/ = wasted memory)
A///
BC//
DEF/
GHIJ
linarized triangular matrix
ABCDEFGHIJ
You can acces linerized triangular matrix element E with coordinates [y,x] = [2,1] (element 'A' taken for origin) like
sum=0;
for(iy=0;iy<y;iy++)
for(ix=0;ix<=y && ix<x;ix++) sum++;
//myLinMatr[sum]=='E'

Resources