1

I am very new to C (started 4 days ago, do have a background in Python and Java). I tried to create a dynamic array (python list) to solve advent of code day 4 part 2. The own list and win list works normally, I don't understand why the cardInstancesCount just refused to take in a value.

Valgrind output

==1444== Invalid write of size 4
==1444==    at 0x1097FD: main (part2.c:91)
==1444==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

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

int is_a_num_char(char *p_char) { return (*p_char >= '0' && *p_char <= '9'); }

int extract_int(char **p_start) {
    char *p_end = *p_start;
    while (is_a_num_char(p_end)) p_end++;
    size_t length = p_end - *p_start;
    char tmp[length + 1];
    tmp[length] = '\0';
    memcpy(tmp, *p_start, length);
    *p_start = p_end;
    return (int)strtol(tmp, (char **)NULL, 10);
}

int main(int argc, char *argv[]) {
    FILE *file = fopen(argv[1], "r");
    int res = 0;
    char buffer[500];
    int tmpNum;
    int cardQuantity = 0;
    int *cardInstancesCount = NULL;

    for (int cardIdx = 0; fgets(buffer, sizeof(buffer), file); cardIdx++) {
        int *win = NULL;
        int *own = NULL;
        int winIdx = 0;
        int ownIdx = 0;
        int matchCount = 0;

        char *p_line = buffer;
        // Skip to ':'
        while (*p_line != ':') p_line++;

        // Load list of winning numbers
        for (; *p_line != '|'; p_line++) {
            if (!is_a_num_char(p_line)) {
                continue;
            }
            tmpNum = extract_int(&p_line);
            int *tmp = realloc(win, sizeof(int) * (winIdx + 1));
            if (tmp == NULL) {
                printf("%s\n", "Memory Allocation Failed");
                return 1;
            }
            win = tmp;
            win[winIdx++] = tmpNum;
        }

        // Load list of own numbers
        for (; *p_line != '\0'; p_line++) {
            if (!is_a_num_char(p_line)) {
                continue;
            }
            tmpNum = extract_int(&p_line);
            int *tmp = realloc(own, sizeof(int) * (ownIdx + 1));
            if (tmp == NULL) {
                printf("%s\n", "Memory Allocation Failed");
                return 1;
            }
            own = tmp;
            own[ownIdx++] = tmpNum;
        }

        // Check how many matchings
        for (int ownCheckIdx = 0; ownCheckIdx < ownIdx; ownCheckIdx++) {
            for (int winCheckIdx = 0; winCheckIdx < winIdx; winCheckIdx++) {
                if (own[ownCheckIdx] == win[winCheckIdx]) {
                    matchCount++;
                    break;
                }
            }
        }
        free(win);
        free(own);

        if (cardQuantity == cardIdx) {
            printf("%p\n", &cardInstancesCount);
            int *tmp =
                realloc(cardInstancesCount, sizeof(int) * (cardQuantity + 1));
            if (tmp = NULL) {
                printf("%s\n", "Memory Allocation Failed");
                return 1;
            }
            cardInstancesCount = tmp;
            printf("%p\n", &cardInstancesCount);
            cardInstancesCount[cardIdx] = 1; // Line 91
            printf("%s\n", "no");
            printf("%d",*cardInstancesCount);
        }

        // If need to expand cardQuantity
        int newCardQuantity = cardIdx + matchCount + 1;
        if (newCardQuantity > cardQuantity) {
            int *tmp =
                realloc(cardInstancesCount, sizeof(int) * newCardQuantity);
            if (tmp == NULL) {
                printf("%s\n", "Memory Allocation Failed");
                return 1;
            } else {
                cardInstancesCount = tmp;
            }

            // Initialise all 1 for new card discovery
            for (int i = cardQuantity; i < newCardQuantity; i++) {
                cardInstancesCount[i] = 1;
            }
            cardQuantity = newCardQuantity;

            // Add current instance to the cards
            for (int i = cardIdx + 1; i < newCardQuantity; i++) {
                cardInstancesCount[i] += cardInstancesCount[cardIdx];
            }
            // Set newCardQuantity
            cardQuantity = newCardQuantity;
        }
        // If no cardQuantity expansion.
        else {
            for (int i = cardIdx + 1; i < newCardQuantity; i++) {
                cardInstancesCount[i] += cardInstancesCount[cardIdx];
            }
        }
    }
    for (int i = 0; i < cardQuantity; i++) {
        printf("%d", cardInstancesCount[i]);
    }
    free(cardInstancesCount);
    printf("Res: %d\n", res);
    return 0;
}

The code that works for part 1

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

int is_a_num_char(char *p_char) { return (*p_char >= '0' && *p_char <= '9'); }

int extract_int(char **p_start) {
    char *p_end = *p_start;
    while (is_a_num_char(p_end)) p_end++;
    size_t length = p_end - *p_start;
    char tmp[length + 1];
    tmp[length] = '\0';
    memcpy(tmp, *p_start, length);
    *p_start = p_end;
    return (int)strtol(tmp, (char **)NULL, 10);
}

int main(int argc, char *argv[]) {
    FILE *file = fopen(argv[1], "r");
    int res = 0;
    char buffer[500];
    int tmpNum;

    while (fgets(buffer, sizeof(buffer), file)) {
        int *win = NULL;
        int *own = NULL;
        int winIdx = 0;
        int ownIdx = 0;
        int matchCount = 0;

        char *p_line = buffer;
        while (*p_line != ':') p_line++;
        for (; *p_line != '|'; p_line++) {
            if (!is_a_num_char(p_line)) {
                continue;
            }
            tmpNum = extract_int(&p_line);
            int *tmp = realloc(win, sizeof(int) * (winIdx + 1));
            if (tmp == NULL) {
                printf("%s\n", "Memory Allocation Failed");
                return 1;
            }
            win = tmp;
            win[winIdx++] = tmpNum;
        }
        for (; *p_line != '\0'; p_line++) {
            if (!is_a_num_char(p_line)) {
                continue;
            }
            tmpNum = extract_int(&p_line);
            int *tmp = realloc(own, sizeof(int) * (ownIdx + 1));
            if (tmp == NULL) {
                printf("%s\n", "Memory Allocation Failed");
                return 1;
            }
            own = tmp;
            own[ownIdx++] = tmpNum;
        }
        for (int ownCheckIdx = 0; ownCheckIdx < ownIdx; ownCheckIdx++) {
            for (int winCheckIdx = 0; winCheckIdx < winIdx; winCheckIdx++) {
                if (own[ownCheckIdx] == win[winCheckIdx]) {
                    matchCount++;
                    break;
                }
            }
        }
        if (matchCount) {
            res += (int)pow(2, matchCount - 1);
        }
        free(win);
        free(own);
    }
    printf("Res: %d\n", res);
    return 0;
}

I try valgrind, try printing out stuff, try using malloc instead of null to assign the first memory address.

0

1 Answer 1

1
    realloc(cardInstancesCount, sizeof(int) * (cardQuantity + 1));
if (tmp = NULL) {

Line 84. I didn't compare it. Just setting the pointer to NULL.

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

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.