-7

I have a 1 dimensional array in which ive initialized as 0 but for some reason when i go inside a loop and try to increase its contents by one the value at position 0 keeps reverting to 0 even after i increase it by 1.

#include <stdio.h>
#include <stdlib.h>
#define TOTAL_V 3
#define NUM_CANDIDATES 7

int hex_age(unsigned short hex){
    unsigned short age = hex >> 9;
    if (age >18 && age <101)
        return age;
    else return 0;
}
int hex_gender(unsigned short hex){
    unsigned short gender = hex >> 7 & 3;
    return gender;
}
int hex_vote(unsigned short hex){
    unsigned short vote, tmp = hex & 0x7f , count = 0;
    if (tmp == 0)
        return 7;
    for (int i = 0 ; i<7; i++){
        if (tmp & 1 == 1){
            count++;
            vote = i;
        }
        tmp = tmp >> 1;
    }
    if (count > 1)
        return 7;
    return vote;
}

    
int main() {
    int s_votes = 0, f_votes = 0, v_count[NUM_CANDIDATES] = {0};
    unsigned short **v_info, hex_v_info , age , gender , vote;

    FILE *fp;

    fp = fopen("data1.dat" , "r");
    if (fp == NULL){
        fprintf(stderr ,"apotuxe o anoigmos tou arxeiou");
        exit(-1);
    }

    if (feof(fp)){
        fprintf(stderr, "to arxeio einai adeio");
        exit(-1);
    }


    
    while (fscanf(fp ,"%x", &hex_v_info) != EOF){
        age = hex_age(hex_v_info);
        if(age == 0)
            f_votes++;
        else {
            gender = hex_gender(hex_v_info);
            if (gender == 0)
                f_votes++;
            else{
                vote = hex_vote(hex_v_info);
                if (vote == 7)
                    f_votes++;
                else{
                    if (s_votes == 0){
                            v_info = malloc(sizeof(int *));
                            v_info[s_votes] =malloc(sizeof(int)* TOTAL_V);
                    }
                    else{
                        v_info = realloc(v_info , sizeof(int *)*(s_votes+1));
                        v_info[s_votes] = malloc(sizeof(int)*TOTAL_V);
                    }

                    v_info[s_votes][0] = age;
                    v_info[s_votes][1] = gender;
                    v_info[s_votes][2] = vote;
                    v_count[vote]++;
                    s_votes++;
                    }
                }
            }
    }
    fclose(fp);
    for (int i = 0; i<s_votes; i++)
        free(v_info);
    return 0;
}

and for some reason when i use calloc to create the array it doesnt have that problem. Does anyone know why that happens

Draisen
  • 1
  • 1
  • Have you tried running your code line-by-line in a debugger while monitoring the control flow and the values of all variables, in order to determine in which line your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Jan 14 '23 at 02:05
  • Please note that [it is generally expected that you make a debugging attempt yourself before asking for help on Stack Overflow](https://idownvotedbecau.se/nodebugging/). Questions which do not demonstrate any debugging attempt and do not specify what you have learnt in the debugging attempt, are usually not well received. – Andreas Wenzel Jan 14 '23 at 02:05
  • v = realloc(v, ...) will lose data and leak memory if realloc fails. Your program depends on a data file that you haven't supplied. Which of the arrays is it that is being reset? – Allan Wind Jan 14 '23 at 03:00
  • `unsigned short **v_info` but you use sizeof(int *) – Allan Wind Jan 14 '23 at 03:05
  • the v_count array is the one that keeps reseting, sorry forgot to mention it. – Draisen Jan 14 '23 at 11:21
  • and here are the hex values i used 0x5181 0x4f04 0x2BA0 0x49A0 0x8890 0xC082 0x88C0 0x6DA0 0x75C0 0x3301 – Draisen Jan 14 '23 at 11:21

1 Answers1

-1
  1. You declare unsigned short hex_v_info (2 bytes on my system), then read data from with fscanf(fp ,"%x", &hex_v_info) where the format string %x expect the address of an int (4 bytes on my system). This will certainly overwrite data unexpectedly.

  2. unsigned short **v_info but you store an array of int [s_votes]. If your pointers are not uniform this will be a problem.

  3. realloc(NULL, 1) is well defined so just use instead of malloc() of the first element. You need to assign the result of realloc()` to e temporary variable, however, to be able handle NULL. Otherwise you lose data & leak memory.

  4. free(v_info); results in a double free if s_votes > 1, and you still leak the memory you allocate at v_info[i].

#include <stdio.h>
#include <stdlib.h>
#define TOTAL_V 3
#define NUM_CANDIDATES 7

// 0x1111 1110 0000 0000
int hex_age(unsigned short hex){
    unsigned short age = hex >> 9;
    if (age >18 && age < 101)
        return age;
    return 0;
}

// 0x0000 0001 1000 0000
int hex_gender(unsigned short hex){
    unsigned short gender = hex >> 7 & 3; // bit 7 and 6
    return gender;
}

// 0x0000 0000 0111 1111
int hex_vote(unsigned short hex){
    unsigned short vote, tmp = hex & 0x7f , count = 0; // bit 11 through 0
    if (tmp == 0)
        return 7;
    for (int i = 0 ; i<7; i++){
        if ((tmp & 1) == 1){
            count++;
            vote = i;
        }
        tmp = tmp >> 1;
    }
    if (count > 1)
        return 7;
    return vote;
}

int main() {
    int s_votes = 0, f_votes = 0, v_count[NUM_CANDIDATES] = {0};
    unsigned short hex_v_info;
    int **v_info = NULL;

    FILE *fp = fopen("data1.dat" , "r");
    if (!fp){
        fprintf(stderr ,"apotuxe o anoigmos tou arxeiou");
        exit(-1);
    }
    for(;;) {
        int rv = fscanf(fp ,"%hx", &hex_v_info);
        if(rv == EOF) break;
        if(rv != 1) {
            printf("err\n");
            return 1;
        }
        unsigned short age = hex_age(hex_v_info);
        if(!age) {
            f_votes++;
            continue;
        }
        unsigned short gender = hex_gender(hex_v_info);
        if (!gender) {
            f_votes++;
            continue;
        }
        unsigned short vote = hex_vote(hex_v_info);
        if (vote == 7) {
            f_votes++;
            continue;
        }
        int **tmp = realloc(v_info, sizeof *tmp * (s_votes + 1));
        if(!tmp) {
            // handle error: free v_info[i] and v_info?
            return 1;
        }
        v_info = tmp;
        v_info[s_votes] = malloc(sizeof **v_info * TOTAL_V);
        v_info[s_votes][0] = age;
        v_info[s_votes][1] = gender;
        v_info[s_votes][2] = vote;
        v_count[vote]++;
        s_votes++;
    }
    fclose(fp);

    printf("f_votes: %d\n", f_votes);
    for(size_t i = 0; i < s_votes; i++) {
        printf("%zu: %d %d %d\n",
            i,
            v_info[i][0],
            v_info[i][1],
            v_info[i][2]
        );
    }
    for (int i = 0; i< s_votes; i++)
        free(v_info[i]);
    free(v_info);
    return 0;
}

and with input file file:

a081
a082

it appears to process the info data correctly:

f_votes: 0
0: 80 1 0
1: 80 1 1
Allan Wind
  • 23,068
  • 5
  • 28
  • 38