0

I have trouble getting my dynamic int array to work properly. I have tried some examples but still can not get it to work. I think I am doing a minor pointer problem but I cannot figure out what. I want to have a dynamic int array and then from another function add numbers to this array. I have gotten the counter to work.

I have tried putting * at different places and trying my way but I am at this point lacking the knowledge to actually know where the * should be. I know some basics about & and * but apparently not enough

static void counterFunction(int* pointerToArray[], int* count)
{
    while (*count < 10) {
        *(*pointerToArray + *count) = *count;
        *count = *count + 1;
    }
}

static int* writeSortedToArray(void)
{
    // I need to store 1000 numbers at this point
    int* dynamicArray = malloc(1000 * sizeof(int));
    int counter = 0;

    counterFunction(&dynamicArray, &counter);

    return 0;
}

The counter works properly, the dynamic array does not work at all. It only store a 0 according to my debugger (xcode)

5
  • Too many *, static void counterFunction(int* pointerToArray, int* count) enought and while (*count<10) { *(pointerToArray+*count)=*count; *count=*count+1; } Commented May 6, 2019 at 8:49
  • 1
    Ahh and add free(dynamicArray) before end of program Commented May 6, 2019 at 8:50
  • I then get Incompatible integer to pointer conversion assigning to 'int *' from 'int'; remove * And the array turn into NULL after first loop Commented May 6, 2019 at 8:55
  • Unable to reproduce your issue. It's printing 10 elements when I tried to print the contents of dynamicArray in a for loop terminating when variable reaches counter value. Commented May 6, 2019 at 9:17
  • 2
    Can you make the program that you posted more complete? How are you calling the functions? Commented May 6, 2019 at 9:19

4 Answers 4

3

To add to the other answers, I'd suggest a more generic approach and encapsulation of the management logic:

#include <assert.h>   // assert()
#include <stddef.h>   // size_t
#include <stdbool.h>  // bool, true, false
#include <stdlib.h>   // malloc(), calloc(), free(), EXIT_FAILURE, EXIT_SUCCESS
#include <stdio.h>    // fputs(), printf(), putchar()

typedef int value_type;
char const *conversion_specifier  = "%d"
size_t const initial_capacity     =  10
size_t growth_factor              =   2

typedef struct dynarray_tag {
    size_t size;
    size_t capacity;
    value_type *data;
} dynarray_t;

dynarray_t dynarray_create(void)
{
    dynarray_t new_dynarray = { 0, 0, NULL };
    return new_dynarray;
}

dynarray_t dynarray_create_reserve(size_t capacity)
{
    dynarray_t new_dynarray = { 0, capacity, NULL };
    new_dynarray.data = malloc(capacity * sizeof *new_dynarray.data);
    return new_dynarray;
}

dynarray_t dynarray_create_size(size_t size)
{
    dynarray_t new_dynarray = { size, size, NULL };
    new_dynarray.data = calloc(size, sizeof *new_dynarray.data);
    return new_dynarray;
}

bool dynarray_is_valid(dynarray_t const *dynarray)
{
    if (!dynarray)
        return false;

    if (!dynarray->size && !dynarray->capacity && !dynarray->data)
        return true;

    if (dynarray->size > dynarray->capacity)
        return false;

    if (dynarray->capacity && dynarray->data)
        return true;

    return false;
}

size_t dynarray_get_size(dynarray_t const *dynarray)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray->size;
}

size_t dynarray_get_capacity(dynarray_t const *dynarray)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray->capacity;
}

value_type* dynarray_at(dynarray_t *dynarray, size_t position)
{
    assert(dynarray_is_valid(dynarray) && dynarray->size && position < dynarray->size);
    return &dynarray->data[position];
}

value_type* dynarray_front(dynarray_t *dynarray)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray_at(dynarray, 0);
}

value_type* dynarray_back(dynarray_t *dynarray)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray_at(dynarray, dynarray->size - 1);
}

bool dynarray_reserve(dynarray_t *dynarray, size_t new_capacity)
{
    assert(dynarray_is_valid(dynarray));

    if (new_capacity <= dynarray->capacity)
        return true;

    if (new_capacity < dynarray->size)
        return false;

    value_type *new_data = realloc(dynarray->data, new_capacity * sizeof *new_data);
    if (!new_data)
        return false;

    dynarray->data = new_data;
    dynarray->capacity = new_capacity;

    return true;
}

bool dynarray_resize(dynarray_t *dynarray, size_t new_size)
{
    assert(dynarray_is_valid(dynarray));

    if (new_size <= dynarray->capacity)
        return true;

    value_type *new_data = realloc(dynarray->data, new_size * sizeof *new_data);
    if (!new_data)
        return false;

    dynarray->data = new_data;
    dynarray->size = new_size;
    dynarray->capacity = new_size;

    return true;
}

bool dynarray_insert(dynarray_t *dynarray, size_t position, value_type value)
{
    assert(dynarray_is_valid(dynarray));

    if (dynarray->size + 1 > dynarray->capacity) {
        size_t new_capacity = dynarray->capacity ? dynarray->capacity * growth_factor : initial_capacity;
        if (!dynarray_reserve(dynarray, new_capacity))
            return false;
    }

    for (size_t i = dynarray->size; i > position; --i)
        dynarray->data[i] = dynarray->data[i - 1];

    dynarray->data[position] = value;
    dynarray->size++;

    return true;
}

bool dynarray_push_front(dynarray_t *dynarray, value_type value)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray_insert(dynarray, 0, value);
}

bool dynarray_push_back(dynarray_t *dynarray, value_type value)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray_insert(dynarray, dynarray->size, value);
}

bool dynarray_insert_sorted(dynarray_t *dynarray, value_type value)
{
    assert(dynarray_is_valid(dynarray));

    if (!dynarray_get_size(dynarray) || value < *dynarray_front(dynarray))
        return dynarray_push_front(dynarray, value);

    if (value > *dynarray_back(dynarray))
        return dynarray_push_back(dynarray, value);

    size_t insert_pos = 0;
    for (; insert_pos < dynarray->size && value > dynarray->data[insert_pos]; ++insert_pos);
    return dynarray_insert(dynarray, insert_pos, value);
}

void dynarray_print(dynarray_t const *dynarray)
{
    assert(dynarray_is_valid(dynarray));

    for (size_t i = 0; i < dynarray->size; ++i) {
        printf(conversion_specifier, dynarray->data[i]);
        if (i + 1 < dynarray->size)
            printf(", ");
    }
}

void dynarray_sort(dynarray_t *dynarray)  // insertion sort
{
    assert(dynarray_is_valid(dynarray));

    for (size_t i = 1; i < dynarray->size; i++) {
        value_type key = dynarray->data[i];

        size_t k = i - 1;
        for (; k >= 0 && dynarray->data[k] > key; --k)
            dynarray->data[k + 1] = dynarray->data[k];

        dynarray->data[k + 1] = key;
    }
}

void dynarray_free(dynarray_t *dynarray)
{
    assert(dynarray_is_valid(dynarray));

    free(dynarray->data);
    dynarray->size = dynarray->capacity = 0;
    dynarray->data = NULL;
}

int main(void)
{
    dynarray_t arr = dynarray_create();

    if (!dynarray_is_valid(&arr)) {
        fputs("Not enough memory. :(\n\n", stderr);
        return EXIT_FAILURE;
    }

    int result = EXIT_FAILURE;

    for (value_type i = 2; i < 15; i += 2) {
        if (!dynarray_push_back(&arr, i))
            goto error_exit;
    }
    dynarray_print(&arr);
    putchar('\n');

    for (value_type i = 1; i < 14; i += 2) {
        if (i != 7) {
            if (!dynarray_push_front(&arr, i))
                goto error_exit;            
        }
    }
    dynarray_print(&arr);
    putchar('\n');

    dynarray_sort(&arr);
    dynarray_print(&arr);
    putchar('\n');

    if (!dynarray_insert_sorted(&arr, 0))
        goto error_exit;
    dynarray_print(&arr);
    putchar('\n');

    if (!dynarray_insert_sorted(&arr, 15))
        goto error_exit;
    dynarray_print(&arr);
    putchar('\n');

    if (!dynarray_insert_sorted(&arr, 7))
        goto error_exit;
    dynarray_print(&arr);
    putchar('\n');

    result = EXIT_SUCCESS;

error_exit:
    result == EXIT_FAILURE && fputs("Not enough memory. :(\n\n", stderr);
    dynarray_free(&arr);
    return result;
}

Output:

2, 4, 6, 8, 10, 12, 14
13, 11, 9, 5, 3, 1, 2, 4, 6, 8, 10, 12, 14
1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14
0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14
0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

Todo:

  • dynarray_insert_range()
  • dynarray_create_init() from iterator pair
  • dynarray_from_file()
  • dynarray_copy()
  • dynarray_begin()
  • dynarray_end()
  • ...
Sign up to request clarification or add additional context in comments.

Comments

0

You make some mistakes:

1) int* pointerToArray[] is a pointer to pointer(s). You should use int* pointerToArray.

2) *(*pointerToArray+*count)=*count; is dereferencing pointerToArray two times, you should use *(pointerToArray + *count) = *count;.

3) dynamicArrayis already a pointer, you should not use the &operator to get its address. Then counterFunction(&dynamicArray, &counter);should be converted in counterFunction(dynamicArray, &counter);.

Finally, your code should look like:

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

static void counterFunction(int * pointerToArray, int * count){

    while (*count < 10) {
        *(pointerToArray + *count) = *count;
        *count += 1;
    }
}


static int * writeSortedToArray(){

    //I need to store 1000 numbers at this point
    int * dynamicArray = malloc(100 * sizeof(int));
    int counter = 0;

    counterFunction(dynamicArray, &counter);

    // as suggested, finally release the array
    free(dynamicArray);

    return 0;
}

int main(){
    writeSortedToArray();
    return 0;
}

12 Comments

int *pointerToArray? That's nonsense. That's just pointerToInt
why would you return 0; instead of void?
The way he used to initialise an array is nosense, I only tried to make him understand the way pointers work. int [] pointerToArray may be smarter but does the same things as int *pointerToArray. I used return 0 to be consistent with his code, maybe that function was not complete yet.
The thing is you shouldn't call pointerToArray something which is not a pointer to an array, which can only be int (*pointerToArray)[]
You changed the return type from an int * to an int. That's not being consistent.
|
0
static void counterFunction(int array[], int* count)
{
        ptrdiff_t i;

        for (i = *count; i < 10; i++)
                array[i] = i;
        *count = i;
}

static int *writeSortedToArray(void)
{
        //I need to store 1000 numbers at this point
        int *dynamicArray;
        int counter;

        dynamicArray = calloc(sizeof(*dynamicArray) * 1000);
        counter = 0;
        counterFunction(dynamicArray, &counter);
        /* counter == 10 */

        return dynamicArray;
}

First of all, if a function always returns 0, it should be void (except main(), for its own reasons). Although you probably didn't want to return 0, and instead return the array.

The counter function doesn't need to know that the array is dynamic. It can just accept any array, and use it with array notation.

I changed to a for loop, because it's more natural.

You don't need to pass a pointer to the array, and in fact you shouldn't, because then the compiler could notice the difference between a pointer to an array and a pointer to a pointer, and complain.

I don't get the purpose of your code, but this code is just the corrected version of your code.

Remember to free(dynamicArray); at some point.

Comments

-1

Wrong use of pointer here. Your Dynamicarray from the WriteSortedToArray is already an adress so you do not need to pass it as an adress. This should work :

static void counterFunction(int* pointerToArray, int count){

while (count < 10)
{
    pointerToArray[count] = count;
    count++;
 }
}


static int* writeSortedToArray(void){

int* dynamicArray = malloc(1000 * sizeof(int));
int counter = 0;

counterFunction(dynamicArray, counter);

return 0;
}

If you want to keep the value of your counter when exiting your counterFunction which is 10, do this instead :

static void counterFunction(int* pointerToArray, int *count){

while (*count < 10)
{
    pointerToArray[*count] = *count;
    *count++;
 }
}


static int* writeSortedToArray(void){

int* dynamicArray = malloc(1000 * sizeof(int));
int counter = 0;

counterFunction(dynamicArray, &counter);

return 0;
}

You should always free your memory using the free function to avoid memory leak issues.

free(dynamicArray)

5 Comments

I sense global variables and a some misplaced }s.
Explain yourselves ?
int *pointerToArray? That's nonsense. That's just pointerToInt
if a function always returns 0, it should be void (except main(), for its own reasons). Although you probably didn't want to return 0, and instead return the array.
Even if you are right, The question wasnt about it. but we can assume the int* was intended for returning the array later on.

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.