Rahul Choudhary
Rahul Choudhary

Reputation: 309

Why infinite loop

I'm making a function that takes a string as input and stores the occurrence of letters from a-z in a map called map1. I have no idea why the output is going beyond 122 ( int('z') ). I also tried while loop, just in case. Here is the code

#include <bits/stdc++.h>
using namespace std;

void makeAnagram(string a) {
    int map1[122][2];
    for(int i='a';i<='z';i++)
        map1[i][1] = 0;
    for(int i=0;i<a.size();i++)
        map1[a[i]][1]++;
    for(int i='a';i<='z';i++)
    {
        cout<<char(i)<<": "<<map1[i][1]<<endl;
    }
}

int main()
{
    string s ="abcwedddf";
    makeAnagram(s);
    return 0;
}

The output is

a: 1
b: 1
c: 1
d: 3
e: 1
f: 1
g: 0
h: 0
i: 0
j: 0
k: 0
l: 0
m: 0
n: 0
o: 0
p: 0
q: 0
r: 0
s: 0
t: 0
u: 0
v: 0
w: 1
x: 0
y: 0
z: 0
{: 32766
|: 32766
}: 21938
~: 32766
: 0
<and continued>.....

Runtime error: SIGSEGV

Upvotes: 2

Views: 125

Answers (2)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122840

If (int)'z' is 122 (not necessarily the case), then in your loops you are accessing map1[122][1], which is the second element of the 123th element, but the array has only 122x2 elements. Also there are lots of elements in that array you are not using at all. a is not 0 and it is not clear what the second dimension is for. Counting frequencies is easiest done with a std::map (or unordered_map in case you dont care about sorting):

#include <map>
#include <iostream>
using namespace std;

void makeAnagram(string a) {
    std::map<char,unsigned> map1;

    for (auto c : a) map1[c]++;

    for (const auto& e : map1) {
        std::cout << e.first << ": " << e.second << "\n";
    }
}

Upvotes: 2

R Sahu
R Sahu

Reputation: 206697

Let's assume for a moment that you are counting on ASCII encoding.

You are accessing map1 using out of bounds index when the character is '~'. The integer value of '~' is 126. Consequently, your program has undefined behavior.

You can solve the problem by using

std::map<char, int> map1;

If you want to make sure that it has an item for certain set of characters, you can initialize it accordingly.

std::string init_string = "abcdefgh";
for ( char c : init_string )
{
   map1[c] = 0;
}

Upvotes: 3

Related Questions