0

I want to append numbers to an empty array and the amount of these numbers is unknown at the start. For example, generating numbers from 1 to 10 and appending one after another.

generateFromOneToTen will save my result in output and count should be 10 after execution. Everything's alright if I print the result in this function.

int generateFromOneToTen(int *output, int count)
{
    for (int i = 0; i < 10; i++) {
        output = arrayAppendInt(output, i + 1, count);
        count++;
    }

    // Print result of `output` is 1,2,3...10 here

    return count;
}

And I implemented arrayAppendInt to dynamic increase the length of an array and append new value after the old ones.

int *arrayAppendInt(int *array, int value, int size) 
{
    int newSize = size + 1;
    int *newArray = (int*) realloc(array, newSize * sizeof(int));

    if (newArray == NULL) {
        printf("ERROR: unable to realloc memory \n");
        return NULL;
    }

    newArray[size] = value;

    return newArray;
}

Here comes the question. When invoking the generation function, numbers will always be NULL. How can I return the generated numbers to the numbers variable?

int *numbers = NULL;
int count = 0;
count = generateFromOneToTen(numbers, 0);
                             ^^^^^^^
3
  • man realloc():: ... if ptr is NULL, then the call is equivalent to malloc(size), for all values of size;... Commented May 10, 2018 at 9:11
  • So you want to modify the argument numbers of the function? Possible duplicate? Commented May 10, 2018 at 9:11
  • The cleanest solution is IMHO to pack the array+the bookkeeping (size,used) into a structure, and use (a pointer to) this structure as an argument. Commented May 10, 2018 at 9:17

3 Answers 3

3

You could use a pointer to a pointer of integer (int **):

int generateFromOneToTen(int **output, int count)
{
    for (int i = 0; i < 10; i++) {
        *output = arrayAppendInt(*output, i + 1, count);
        count++;
    }
    // `*output` is 1,2,3...10 here
    return count;
}

You could re-write the arrayAppendInt function like that:

int *arrayAppendInt(int *array, int value, int size) 
{
    int newSize = size + 1;
    int *newArray;
    if (array==NULL)
      newArray = (int*) malloc ((1+size) * sizeof(int));
    else
      newArray = (int*) realloc(array, newSize * sizeof(int));

    if (newArray == NULL) {
        printf("ERROR: unable to realloc memory \n");
        return NULL;
    }

    newArray[size] = value;

    return newArray;
}

And call it like that *output = arrayAppendInt(*output, i + 1, i);.

Sign up to request clarification or add additional context in comments.

5 Comments

How to modify arrayAppendInt then?
I updated my answer with modifications to arrayAppendInt. Here is the full synthesis of my answers : taas.trust-in-soft.com/tsnippet/t/856bfc98
I needn't change arrayAppendInt I think.
I agree, no need to change actually!
if (array==NULL) newArray = (int*) malloc ((1+size) * sizeof(int)); You dont need the special case. (and you dont need the cast,either)
0

The cleanest solution is (in my opinion) to pack the array+the bookkeeping (size,used) into a structure, and use (a pointer to) this structure as an argument.


#include <stdlib.h>

struct dopedarray {
        unsigned size;
        unsigned used;
        int *array;
        };

Now you can put all your allocation and bookkkeeping stuff into a single function (which can be inlined) :


int array_resize(struct dopedarray *ap, unsigned newsize)
{
int *newp;

if(!ap) return -1;

newp = realloc (ap->array, newsize*sizeof*ap->array);
  // check return value here...
if (!newp) return -1;

free(ap->array);
ap->array = newp;
ap->size = newsize;

  // bookkeeping sanity
if(ap->size > ap->used ) { ap->used > ap->size; }

return 0;
}

The add_element function needs to be changed a bit, too:


int array_add_element(struct dopedarray *ap, int value)
{
if(ap->used >= ap->size){
        unsigned newsz;
        newsz= ap->used ? 2*ap->used: 4;
        array_resize(ap, newsz);
        // check return value here...
        }

ap->array[ap->used++] = val;
return 0;
}

Comments

0

The complete code to my question:

int generateFromOneToTen(int **output, int count) // +
{
    for (int i = 0; i < 10; i++) {
        *output = arrayAppendInt(*output, i + 1, count); // ++
        count++;
    }

    return count;
}

int *arrayAppendInt(int *array, int value, int size) 
{
    int newSize = size + 1;
    int *newArray = (int*) realloc(array, newSize * sizeof(int));

    if (newArray == NULL) {
        printf("ERROR: unable to realloc memory \n");
        return NULL;
    }

    newArray[size] = value;

    return newArray;
}

int *numbers = NULL;
int count = 0;
count = generateFromOneToTen(&numbers, 0); // +

This answer also worths reading: https://stackoverflow.com/a/9459803/1951254

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.