-3

I'm working on a dynamic allocation project and I get a constant unexpected answer for a test case. The output consistently prints out 'test of size: 11' and I can't figure out why.

getSize() goes through all the values and adds to the count if it's not NULL (in practice, counts all the valid elements in the array).

I'm using getSize() as a fallback incase the var in ArrayList size does not output correctly. Also, the array's created using calloc() and referenced to test is wacky. If I do a for loop to print out all the values, it stops midway and crashes (in the case of array of size 25, it consistently stops after index 7.) However, if I printf the index if seg faults on with the loop, it works perfectly. Is the logic wrong, or do I have to flush something?

If I change the test case to where the size of array is bigger or larger, the same thing happens where there is a constant int printing out.

typedef struct ArrayList
{
    // We will store an array of strings (i.e., an array of char arrays)
    char **array;

    // Size of list (i.e., number of elements that have been added to the array)
int size;

    // Length of the array (i.e., the array's current maximum capacity)
    int capacity;

} ArrayList;

int main(void){
    struct ArrayList *test;
    test=createArrayList(25);
    int i=getSize(test);
    printf("test of size: %d", i);
    return 0;
}

//creates the array list and allocated memory for it
ArrayList *createArrayList(int length){
    struct ArrayList *r = malloc(sizeof(*r));
    if (r == NULL)//Returns null if malloc does not work
        return NULL;
    length=(length<DEFAULT_INIT_LEN) ? DEFAULT_INIT_LEN: length;//figures which value is         greater and keeps it
    r->array=calloc(sizeof(char), (length+1));
    if (r->array == NULL){//returns null if malloc does not work
            printf("error\n");
            return NULL;
    }
    r->size = 0;
    r->capacity = length;
    printf("Created new ArrayList of size %d.\n", length);
    return r;
}
//the function im having trouble with
int getSize(ArrayList *list){
    int i=0, count=0;//index variables
    if (list->array==NULL)
        return -1;
    for (i=0; i<(list->capacity-1); i++){//goes through all indexs of internal array and     conuts valid elements. this is where im having trouble specifically
        if (list->array[i]!=NULL)
            count++;
    }
    return count;
}
Hammad
  • 49
  • 6
  • You forgot to free `r` on `calloc` failure again... – user3125367 Feb 02 '14 at 19:20
  • And I told you about `sizeof(char)`. Why didn't you at least analyze the differences from your original version? – user3125367 Feb 02 '14 at 19:21
  • possible duplicate of [Calling Function with type struct and returning pointer does not run](http://stackoverflow.com/questions/21506725/calling-function-with-type-struct-and-returning-pointer-does-not-run) –  Feb 02 '14 at 19:24
  • I'm very new to programming, thanks for being patient with me. I havn't covered deallocation in depth yet, this is my first attempt with it. – Hammad Feb 02 '14 at 19:47

2 Answers2

0

This is wrong:

r->array=calloc(sizeof(char), (length+1));

It should be sizeof(char *), since you're allocating space for an array of pointers to char. Or, even better, don't hardcode the type of the array elements at all, and use *r->array instead:

r->array = calloc(sizeof(*r->array), length+1);

It also feels a little weird that you allocate length+1 elements and then only go up to capacity-1 in getSize(). I think you just want length.

Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70
  • first is good, second crashes, because r->array is not yet allocated, so *r->array points to nowhere – esskar Feb 02 '14 at 19:23
  • 5
    @esskar: Wrong. `sizeof(*r->array)` is evaluated at compile time; it is used only to infer the type. It is absolutely valid. – Filipe Gonçalves Feb 02 '14 at 19:24
  • It's amazing how a small thing like that can change the entire functionality of the program. I guess it just adds to the excitement when when everything just works perfectly. Thanks! – Hammad Feb 02 '14 at 19:28
0

It seems to me that this part tries to index list elements that do not exist:

for (i = 0; i < (list->capacity - 1); i++)
{
    if(list->array[i] != NULL)
        count++;
}

Maybe this is better for what you're trying to accomplish:

while (list->array[i++] != NULL)
{
    count++;
}
gmorrow
  • 101
  • 4
  • correct me if I'm wrong, but the while loop will not account for cases where the non NULL elements are not consecutive? – Hammad Feb 02 '14 at 19:48
  • @Hammad: You're not wrong. It just seemed natural for me to assume that they are. – gmorrow Feb 02 '14 at 19:58