0

I am entirely new to C and I have this code as shown below:

//Initialize Global array variable title_char_cnt_array to char[26]
char title_char_cnt_array[26];
//Initialize SearchTitle array
char *SearchTitle[6] = { "uuul", "dule", "speed", "spede", "deul", "cars" };

char *Compute_HashMapKey_for_each_title(char title[]) {
    //char *T;
    //T = title;
    Get_Individual_Character_Frequency_For_Each_Title(title);
    //Initialize alphabets array to char and assign a to z
    //Initialize HashMapKey to char
    char *HashMapKy;
    HashMapKy = malloc(sizeof(char));
    char default_str[] = { "0#" };
    char str[50];
    char ash[] = { "#" };
    int i;
    //Create HashMapKey by appending 0# to HashMapKey if a particular alphabet isn't in title or   count_of_alphabet plus # if the alphabet is in title (the format is   1#0#1#0#1#0#0#0#0#0#0#0#0#0#1#0#0#2#0#2 ... #1#0#0# for this title: Extractor for e.g)
    for (i = 0; i < 26; i++) {
        if (title_char_cnt_array[i] == 0) {
            //HashMapKey = HashMapKey . '0#';
            strcat(HashMapKy, default_str);
        } else {
            //First convert character frequency count to string
            sprintf(str, "%d", title_char_cnt_array[i]);
            //concat # to str
            strcat(str, ash);
            //HashMapKey =. title_char_cnt_array[i].'#';
            strcat(HashMapKy, str);
        }//end if
    }//End For
    return HashMapKy;
}

void Get_Individual_Character_Frequency_For_Each_Title(char Title[]) {
    int Title_Size;
    //get size of Title
    Title_Size = strlen(Title);
    int x, j;
    //Initialize current_char to char for character comparison in title_array
    char current_char;
    char Alphabets[][1] =  { "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z" };
    //Foreach character in title array, calculate individual character frequency here
    for (x = 0; x < Title_Size; x++) {
        //Initialize current_char_cnt to 0
        int current_char_cnt = 1;
        current_char = *(Title + x);//retrieve each character of Title array
        for (j = x; j < Title_Size; j++) {
            if (current_char == *(Title + j + 1)) {
                //increment current_char_cnt
                current_char_cnt++;
            }//End If
        }
        /*Insert current_char_cnt in title_char_cnt_array against index - index no. represents position of char in alphabetical order*/
        if (current_char == Alphabets[0][0])
            if (title_char_cnt_array[0] == 0)//if no previous value inserted, then insert
                title_char_cnt_array[0] = current_char_cnt;
        if (current_char == Alphabets[1][0])
            if (title_char_cnt_array[1] == 0)
                title_char_cnt_array[1] = current_char_cnt;
        if (current_char == Alphabets[2][0])
            if (title_char_cnt_array[2] == 0)
                title_char_cnt_array[2] = current_char_cnt;
        if (current_char == Alphabets[3][0])
            if (title_char_cnt_array[3] == 0)
                title_char_cnt_array[3] = current_char_cnt;
        if (current_char == Alphabets[4][0])
            if (title_char_cnt_array[4] == 0)
                title_char_cnt_array[4] = current_char_cnt;
        if (current_char == Alphabets[5][0])
            if (title_char_cnt_array[5] == 0)
                title_char_cnt_array[5] = current_char_cnt;
        if (current_char == Alphabets[6][0])
            if (title_char_cnt_array[6] == 0)
                title_char_cnt_array[6] = current_char_cnt;
        if (current_char == Alphabets[7][0])
            if (title_char_cnt_array[7] == 0)
                title_char_cnt_array[7] = current_char_cnt;
        if (current_char == Alphabets[8][0])
            if (title_char_cnt_array[8] == 0)
                title_char_cnt_array[8] = current_char_cnt;
        if (current_char == Alphabets[9][0])
            if (title_char_cnt_array[9] == 0)
                title_char_cnt_array[9] = current_char_cnt;
        if (current_char == Alphabets[10][0])
            if (title_char_cnt_array[10] == 0)
                title_char_cnt_array[10] = current_char_cnt;
        if (current_char == Alphabets[11][0])
            if (title_char_cnt_array[11] == 0)
                title_char_cnt_array[11] = current_char_cnt;
        if (current_char == Alphabets[12][0])
            if (title_char_cnt_array[12] == 0)
                title_char_cnt_array[12] = current_char_cnt;
        if (current_char == Alphabets[13][0])
            if (title_char_cnt_array[13] == 0)
                title_char_cnt_array[13] = current_char_cnt;
        if (current_char == Alphabets[14][0])
            if (title_char_cnt_array[14] == 0)
                title_char_cnt_array[14] = current_char_cnt;
        if (current_char == Alphabets[15][0])
            if (title_char_cnt_array[15] == 0)
                title_char_cnt_array[15] = current_char_cnt;
        if (current_char == Alphabets[16][0])
            if (title_char_cnt_array[16] == 0)
                title_char_cnt_array[16] = current_char_cnt;
        if (current_char == Alphabets[17][0])
            if (title_char_cnt_array[17] == 0)
                title_char_cnt_array[17] = current_char_cnt;
        if (current_char == Alphabets[18][0])
            if (title_char_cnt_array[18] == 0)
                title_char_cnt_array[18] = current_char_cnt;
        if (current_char == Alphabets[19][0])
            if (title_char_cnt_array[19] == 0)
                title_char_cnt_array[19] = current_char_cnt;
        if (current_char == Alphabets[20][0])
            if (title_char_cnt_array[20] == 0)
                title_char_cnt_array[20] = current_char_cnt;
        if (current_char == Alphabets[21][0])
            if (title_char_cnt_array[21] == 0)
                title_char_cnt_array[21] = current_char_cnt;
        if (current_char == Alphabets[22][0])
            if (title_char_cnt_array[22] == 0)
                title_char_cnt_array[22] = current_char_cnt;
        if (current_char == Alphabets[23][0])
            if (title_char_cnt_array[23] == 0)
                title_char_cnt_array[23] = current_char_cnt;
        if (current_char == Alphabets[24][0])
            if (title_char_cnt_array[24] == 0)
                title_char_cnt_array[24] = current_char_cnt;
        if (current_char == Alphabets[25][0])
            if (title_char_cnt_array[25] == 0)
                title_char_cnt_array[25] = current_char_cnt;
    }//End For
}

int main() {
    int i;
    //Foreach element in title_char_cnt_array, assign an in value of -1
    for (i = 0; i < 26; i++)
        title_char_cnt_array[i] = 0;

    //Initialize HashMap array
    struct node *HashMap[9];
    int HM_indx = 0;
    for (HM_indx = 0; HM_indx < 9; HM_indx++)
        HashMap[HM_indx] = NULL;
    int sz = 6; //6 titles to insert in hashmap
    //Initialize SearchTitle array
    //char *SearchTitle[6] = { "uuul", "dule", "speed", "spede", "deul", "cars" };

    char *HMKey;
    int x;
    for (x = 0; x < sz; x++) {
        HMKey = Compute_HashMapKey_for_each_title(SearchTitle[x]);
        //printf("%s\n", HMKey);
        Insert_Title_To_HashMap_Using_HashMapKey(x, HMKey, HashMap);
    }

    free(HMKey);
    return 0;
}

What I expect Compute_HashMapKey_for_each_title(SearchTitle[x]) to return to HMKey in main function is:

HashMapKey="0#0#0#0#0#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#3#0#0#0#0#0#"

But what I see instead using the debugger is:

HashMapKey=0xb41700 "À", '«' <repeats 16 times>, "þîþîþîþîþîþîþîþ0#0#0#0#0#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#3#0#0#0#0#0#"

As you can see from the main function, once I get HMKey; I pass it to the function Insert_Title_To_HashMap_Using_HashMapKey(x, HMKey, HashMap) and then break up my expected string: "0#0#0#0#0#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#3#0#0#0#0#0#" into single characters, typecast each character to its ASCII number and sum then up. So I expect to see 0 as the first character, # as the second character, 0 as the third character and so on, but what I see as the first character using the debugger is À which is the first character after the address in the return value of Compute_HashMapKey_for_each_title(SearchTitle[x]) to return to HMKey.

Even my expected strlen in this case should be 52 but instead what I see is: 84.

I have no idea what's going on, please any help will be highly appreciated.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
eedideyahoocom
  • 143
  • 1
  • 8
  • 1
    If you are new to C, then don't take such a complex piece of code to start with. Start with "hello world" – Paul Ogilvie May 08 '21 at 12:49
  • Does this answer your question? [malloc puts "garbage" values](https://stackoverflow.com/questions/44519672/malloc-puts-garbage-values) – Raymond Chen May 08 '21 at 13:13

3 Answers3

2
HashMapKy = malloc(sizeof(char));

You only allocate space for a single character. Arrays or memory in C is not dynamic, you can't "extend" memory or arrays by just appending to them.

Furthermore, the strcat function requires both the strings to be null-terminated strings. Since the malloc function does not initialize the memory it allocates in anyway, its contents will be indeterminate (best to look at it as garbage or random). It's unlikely to contain a zero (the null terminator) at its first position.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

You should malloc size to HashMapKy = (char*) malloc (sizeof(char) * 25);

  • 25 bytes is not enough for this string. The hash string can be as long as 130 bytes and `* HashMapKy` must be set to zero before the construction loop. – chqrlie May 08 '21 at 13:17
0

There is a major problem in Compute_HashMapKey_for_each_title: you do not allocate enough space for the hash string, malloc(sizeof(char)) allocates a single byte.

The string can be as large as 26 times 5 plus the null terminator (5 bytes if title_char_cnt_array is an array of char, but 12 if you change that to int). I suggest using a local array and returning an allocated copy using strdup():

char *Compute_HashMapKey_for_each_title(char title[]) {
    char buf[26 * 12 + 1];
    int pos = 0;
    Get_Individual_Character_Frequency_For_Each_Title(title);
    // Create HashMapKey by appending the number of occurrences for each character
    //  followed by a `#` char.
    for (int i = 0; i < 26; i++) {
        pos += sprintf(buf + pos, "%d#", title_char_cnt_array[i]);
    }
    return strdup(buf);
}

The function Get_Individual_Character_Frequency_For_Each_Title can be greatly simplified:

void Get_Individual_Character_Frequency_For_Each_Title(char Title[]) {
    const char *alphabet = "abcdefghijklmnopqrstuvwyxz";
    for (int i = 0; i < 26; i++) {
        title_char_cnt_array[i] = 0;
    }
    for (int i = 0; Title[i] != '\0'; i++) {
        char *p = strchr(alphabet, Title[i]);
        if (p != NULL) {
            title_char_cnt_array[p - alphabet] += 1;
        }
    }
}

If you can assume the system uses thee ASCII character set, the function can be even simpler:

void Get_Individual_Character_Frequency_For_Each_Title(char Title[]) {
    for (int i = 0; i < 26; i++) {
        title_char_cnt_array[i] = 0;
    }
    for (int i = 0; Title[i] != '\0'; i++) {
        char c = Title[i];
        if (c >= 'a' && c <= 'z') {
            title_char_cnt_array[c - 'a'] += 1;
        }
    }
}

Note that title_char_cnt_array should be passed as an argument and should have an integer type larger than char.

chqrlie
  • 131,814
  • 10
  • 121
  • 189