C++ 'std::bad_alloc' what(): std::bad_alloc - c++

I am trying to run the below C++ code and I get this error :
Could anyone please help me clarify why is this the issue
Input : input/text_4.txt 9
terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
Aborted (core dumped)
After reading a few similar threads, the solution is to check dynamic memory allocation. However, my code does not have any dynamically allocated memory
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;
vector<string> arrangefile(vector<string>& scale, int width, int &number) {
int beginning = 0; int total = 0;
vector<string> result;
for(int i = 0; i < scale.size(); i++)
{
total += scale[i].size(); // add length of each word
if(total + i - beginning > width) // checking if the value has exceeded the maximum width
{
total -= scale[i].size();
string sentence= "",low="";
int last = i-1;
int space = width - total; // calculate number of spaces in each line
int check = max(last-beginning, 1);
int even = space/check;
while(even--){
low += " ";
}
int mod = space%check;
for(int j = beginning; j <= last; j++)
{
sentence += scale[j]; //find all values in a sentence
if(j < last || beginning == last)
sentence += low; // add the word low to the larger sentence
if(j - beginning < mod)
sentence += " ";
}
result.push_back(sentence); // add the sentence to the vector
number++; // counts the number of sentences
beginning = i;
total = scale[i].size();
}
}
string sentence =""; // for the last line
int last = scale.size()-1;
int check = last-beginning;
int space = width - total - check;
string low="";
while(space--){
low += " ";
}
for(int j = beginning; j <= last; j++)
{
sentence += scale[j];
if(j < last){
sentence += " ";
}
}
sentence += low;
result.push_back(sentence); // // add the sentence to the vector
number++; // counts the number of sentences
return result;
}
int main(){
string filepath, word;
int M, number=0;
cin >> filepath;
cin >> M;
ifstream fin;
fin.open(filepath.c_str());
unsigned found = filepath.find_last_of("/");
string b = filepath.substr(found+1);
int create = b.size();
string between = b.substr(0, create-4);
string final = between + "_formatted.txt";
string ending = "output/" + final;
mkdir ("output", 0777);
ofstream fout;
fout.open(ending);
for(int i = 0, count = 0; i<M; i++, count ++){
if(count == 9){
fout<<count;
count = -1;
}
else
fout<<count;
}
fout<<endl;
vector <string> first;
vector <string> second;
while(fin >> word){
first.push_back(word);
}
if(first.empty()){
cout<<"0 formatted lines written to "<< ending<<endl;
}
else{
second = arrangefile(first, M,number);
for (auto i = second.begin(); i != second.end(); ++i)
fout << *i <<endl;
cout<<number<<" formatted lines written to "<<ending<<endl;
}
fin.close();
fout.close();
return 0;
}
input file text_4.txt:
This is because not very many happy things happened
in the lives of the three Baudelaire youngsters.
Input: input/text_4.txt 8

When I run your code, on the i==16 iteration of the outer loop in arrangefile, we get width==8 and total==10, with check==1. As a result, even is initialized to -2, and so the while(even--) loop is (nearly) infinite. So it attempts to add spaces to low until it runs out of memory.
(Note that the memory used by std::string is dynamically allocated, so your code does have dynamic memory allocation. The same for std::vector.)
I haven't analyzed your algorithm closely enough to figure out the correct fix, but it's possible your loop should be while(even-- > 0) instead.
I'll second the tip in the comments to use your debugger, and I'll repost the link: What is a debugger and how can it help me diagnose problems?. That's how I found this bug.
I ran the program under the debugger gdb. It ran for a few seconds, at which point I got suspicious because the program doesn't appear do anything complicated enough to take that much computation time. So I interrupted the program (Ctrl-C) which let me see where it was and what it was doing. I could see that it was within the while(even--) loop. That was also suspicious because that loop should complete very fast. So I inspected the value of even (with the command p even) and saw that it was a large negative number. That could only happen if it had started as a negative number, which logically could only happen if total were greater than width. Inspecting their values I could see that this was indeed the case.
Maybe this will be helpful as you learn more about using your debugger.

Related

execution order for cout in C++

c++
When printing to console, if function execution is sequential it would seem logical the ordered array would be printed after calling insertionSort, however order list does not print until next loop. Any help would be appreciated.
#include <stdio.h>
#include <iostream>
#include <array>
using namespace std;
void insertionSort(int* array, int size) {
for (int i = 1; i < size; i++) {
int key = i - 1;
while (i > 0 && array[key] > array[i] ) {
int tmp = array[i];
array[i] = array[key];
array[key] = tmp;
i -= 1;
key -= 1;
}
}
}
const int ARRAY_MAXSIZE = 5;
int main(void) {
int *array = (int*)calloc(ARRAY_MAXSIZE, sizeof(int));
int input;
cout << "Enter 5 digits\n";
for (int size=0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
insertionSort(array, size);
for (int j=0; j <= size; j++) {
cout << array[j];
}
cout << '\n';
}
}
Console Entry
This is a classic off-by-one error. Your insertionSort expects you to pass the number of elements to sort via the parameter size. But your main loop is always holding a value that is one less than the size immediately after adding an element.
I want to say that bugs like this are easily discovered by stepping through your program's execution with a debugger. If you don't know how to use a debugger, start learning now. It is one of the most important tools used by developers.
Anyway, the quick fix is to change your function call to:
insertionSort(array, size + 1);
However, as Paul McKenzie pointed out in comments, it's a bit crazy to do this every time you add a new element because your function sorts an entire unsorted array. Your array is always nearly sorted except for the last element. You only need to call that function once after your input loop is done:
// Read unsorted data
for (int size = 0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
}
// Sort everything
insertionSort(array, ARRAY_MAXSIZE);
// Output
for (int j = 0; j < ARRAY_MAXSIZE; j++) {
cout << array[j];
}
cout << '\n';
But if you want every insertion to result in a sorted array, you can "slide" each new value into place after inserting it. It's similar to a single iteration of your insertion-sort:
// Sort the last element into the correct position
for (int i = size; i >= 1 && array[i] > array[i - 1]; i--)
{
std::swap(array[i], array[i - 1]);
}
Even better, you don't need to swap all those values. You simply read the value, then shuffle the array contents over to make room, then stick it in the right spot:
// Read next value
cin >> input;
// Shuffle elements to make room for new value
int newPos = size;
while (newPos > 0 && array[newPos - 1] > input) {
array[newPos] - array[newPos - 1];
newPos--;
}
// Add the new value
array[newPos] = input;

2d array comparing with char

I have an array that reads data from a file, the data is binary digits such as 010011001001 and many others so the data are strings which I read in to my 2d array but I am stuck on comparing each value of the array to 0. Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000][12];
int i = 0, zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while(!inFile.eof())
{
for(int i = 0; i < 5000; i++)
{
for(int j = 0; j < 12; j++)
{
inFile >> myArr[i][j];
j++;
}
i++;
}
}
for(int j = 0; j < 12; j++)
{
for(int i = 0; i < 5000; i++)
{
if(myArr[i][j].compare("0") == 0)
{
zeroCount++;
}
else
{
oneCount++;
}
i++;
}
if(zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
j++;
}
}
some input from the text file:
010110011101
101100111000
100100000011
111000010001
001100010011
010000111100
Thank you for editing you question and providing more information. Now, we can help you. You have 2 major misunderstandings.
How does a for loop work?
What is a std::string in C++
Let us start with the for loop. You find an explanation in the CPP reference here. Or, you could look also at the tutorial shown here.
The for loop has basically 3 parts: for (part1; part2; part3). All are optional, you can use them, but no need to use them.
part1 is the init-statement. Here you can declare/define/initialize a variable. In your case it is int i = 0. You define a variable of data type int and initialize it with a value of 0
part2 is the condition. The loop will run, until the condition becomes false. The condition will be check at the beginning of the loop.
part3 is the so called iteration-expression. The term is a little bit misguiding. It is basically a statement that is executed at the end of the loop, before the next loop run will be executed and before the condition is checked again.
In Pseudo code it is something like this:
{
init-statement
while ( condition ) {
statement
iteration-expression ;
}
}
which means for the part of your code for(int j = 0; j < 12; j++)
{
int j = 0; // init-statement
while ( j < 12 ) { // while ( condition ) {
inFile >> myArr[i][j]; // Your loop statements
j++; // Your loop statements PROBLEM
j++; // iteration-expression from the for loop
}
}
And now you see the problem. You unfortunately increment 'j' twice. You do not need to do that. The last part3 of the for loop does this for you already.
So please delete the duplicated increment statements.
Next, the std::string
A string is, as its names says, a string of characters, or in the context of programming languages, an array of characters.
In C we used to write actually char[42] = "abc";. So using really a array of characters. The problem was always the fixed length of such a string. Here for example 42. In such an array you could store only 41 characters. If the string would be longer, then it could not work.
The inventors of C++ solved this problem. They created a dynamic character array, an array that can grow, if needed. They called this thing std::string. It does not have a predefined length. It will grow as needed.
Therefore, writing string myArr[5000][12]; shows that you did not fully understand this concept. You do not need [12], becuase the string can hold the 12 characters already. So, you can delete it. They characters will implicitely be there. And if you write inFile >> myString then the extractor operator >> will read characters from the stream until the next space and then store it in your myString variable, regardless how long the string is.
Please read this tutorial about strings.
That is a big advantage over the C-Style strings.
Then your code could look like:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000];
int zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while (!inFile.eof())
{
for (int i = 0; i < 5000; i++)
{
inFile >> myArr[i];
}
}
for (int i = 0; i < 5000; i++)
{
zeroCount = 0; oneCount = 0;
for (int j = 0; j < 12; j++)
{
if (myArr[i][j]== '0')
{
zeroCount++;
}
else
{
oneCount++;
}
}
if (zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
}
}
But there is more. You use the magic number 5000 for your array of strings. This you do, because you think that 5000 is always big enough to hold all strings. But what, if not? If you have more than 5000 strings in your source file, then your code will crash.
Similar to the string problem for character arrays, we have also a array for any kind of data in C++, that can dynamically grow as needed. It is called std::vector and you can read about it here. A tutorial can be found here.
With that you can get rid of any C-Style array at all. But please continue to study the language C++ further and you will understand more and more.
Ther are more subtle problems in your code like while(!inFile.eof()), but this should be solved later.
I hope I could help

How do online judges pass the input data?

I'm trying to solve this problem from an online judge (Codeforces):
One day Deivis came across two Vectors of integers A and B, and wondered, could it be possible to form the number X by adding an element of A to another element of B?
More formally, it is possible to choose two indexes i and j such that Ai + Bj = x?
Input
The first entry line is two integers n and x. The second line contains n numbers, the vector A. The third and last line contains n numbers, vector B.
Output
Print 1 if it is possible to form the number x from a sum of one element of each vector, and 0 otherwise."
My problem is that I can not fill in the second vector, when the program runs on the site it fills the vector with zeros. I am using C ++, here's my code:
#include <bits/stdc++.h>
using namespace std;
#define MAX 10
int main()
{
int n, x, i = 0, j = 0, resp = 0, sum;
vector<int> vetA(MAX), vetB(MAX);
cin >> n >> x;
while (scanf("%d", &vetA[i]) == 1)
i++;
while (scanf("%d", &vetB[j]) == 1)
j++;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
sum = vetA[i] + vetB[j];
if (sum == x)
{
resp = 1;
goto END;
}
}
}
END: printf("%d", resp);
return 0;
}
I try to use getchar() after each while loop, but seems that on the site it does not do data capture like on a keyboard, and so the second vector isn't receiving any data. I've also tried to capture data as a std::string but that doesn't work.
Can someone help me?
Here are some hints/examples to compare your program to:
#include <iostream> //Include each standard library seperately
#include <vector> //#include <bits/stdc++.h> is bad practice
// Only declare variables as they are used.
int n; // Better coding practice is one variable per line.
int x; // Competitions shouldn't care how many lines.
if (!(std::cin >> n >> x)) //This is basically the same as cin.fail()
{
std::cerr << "Error inputting data.\n";
return 1;
}
// Now create the vectors, after the size has read in.
std::vector<int> vetA(n);
std::vector<int> vetB(n);
// The number of elements is known, so use a "for" loop.
for (size_t i = 0; i < n; ++i)
{
std::cin >> vetA[i];
}
for (size_t i = 0; i < x; ++i)
{
std::cin >> vetB[i];
}
You should add in some error handling because your program will be given some invalid inputs.
The inputs and vector sizes are examples since you didn't specify the input format in your Post.

ACM 1113 - Multiple Morse Matches

I'm trying to solve the ACM 1113 (http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3554) and I think I got a valid solution (at least the output seems to be ok for multiple entries that I've tried), the only problem is my solution is being rejected by the submission system and I don't know why since it doesn't take that long to run on my machine, could anyone please help me?
/*
* Multiple morse matches
*/
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
std::map<char,string> decodeToMorse;
string toMorse(string w){
string morse = "";
for(int i = 0; i < w.size(); i++){
morse = morse + decodeToMorse[w[i]];
}
return morse;
}
int findPossibleTr( string morse, vector<string> dictMorse, vector<string> dictWords, int index){
int count = 0;
for(int i = 0; i < dictMorse.size(); i++){
if(morse.compare( index, dictMorse[i].size(), dictMorse[i]) == 0){
//cout<<"Found " << dictWords[i] << " on index "<<index<<endl;
if(index+dictMorse[i].size()>=morse.size()){
//cout<<"Adding one for "<< dictWords[i]<<endl;
count+=1;
//return 1;
}else{
count += findPossibleTr(morse, dictMorse, dictWords, index+dictMorse[i].size());
}
}
}
return count;
}
int main(){
int ncases;
cin>>ncases;
decodeToMorse['A'] = ".-";
decodeToMorse['B'] = "-...";
decodeToMorse['C'] = "-.-.";
decodeToMorse['D'] = "-..";
decodeToMorse['E'] = ".";
decodeToMorse['F'] = "..-.";
decodeToMorse['G'] = "--.";
decodeToMorse['H'] = "....";
decodeToMorse['I'] = "..";
decodeToMorse['J'] = ".---";
decodeToMorse['K'] = "-.-";
decodeToMorse['L'] = ".-..";
decodeToMorse['M'] = "--";
decodeToMorse['N'] = "-.";
decodeToMorse['O'] = "---";
decodeToMorse['P'] = ".--.";
decodeToMorse['Q'] = "--.-";
decodeToMorse['R'] = ".-.";
decodeToMorse['S'] = "...";
decodeToMorse['T'] = "-";
decodeToMorse['U'] = "..-";
decodeToMorse['V'] = "...-";
decodeToMorse['W'] = ".--";
decodeToMorse['X'] = "-..-";
decodeToMorse['Y'] = "-.--";
decodeToMorse['Z'] = "--..";
for(int i = 0; i < ncases; i++){
vector<string> dictMorse;
vector<string> dictWords;
string morse;
cin >> morse;
int ndict;
cin >> ndict;
for(int j = 0; j < ndict; j++){
string dictw;
cin >> dictw;
dictMorse.push_back(toMorse(dictw));
dictWords.push_back(dictw);
}
cout<<findPossibleTr(morse,dictMorse, dictWords,0)<<endl;
if(ncases != 1 && i != ncases-1)
cout<<endl;
}
}
I've tried the following input:
3
.---.-.---...
7
AT
ATC
COS
OS
A
T
C
.---.--.-.-.-.---...-.---.
6
AT
TACK
TICK
ATTACK
DAWN
DUSK
.........
5
E
EE
EEE
EEEE
EEEEE
And I get the following output (as expected):
5
2
236
Only problem is that when I submit it to the judge system it says the algorithm spends more than its maximum time limit (3s). Any ideas?
Your algorithm runs out of time because it performs an exhaustive search for all distinct phrases within the dictionary that match the given Morse code. It tries every single possible concatenation of the words in the dictionary.
While this does give the correct answer, it takes time exponential in both the length of the given Morse string and the number of words in the dictionary. The question does actually mention that the number of distinct phrases is at most 2 billion.
Here's a simple test case that demonstrates this behavior:
1
... // 1000 dots
2
E
EE
The correct answer would be over 1 billion in this case, and an exhaustive search would have to enumerate all of them.
A way to solve this problem would be to use memoization, a dynamic programming technique. The key observation here is that a given suffix of the Morse string will always match the same number of distinct phrases.
Side note: in your original code, you passed morse, dictMorse and dictWords by value to your backtracking function. This results in the string and the two vectors being copied at every invocation of the recursive function, which is unnecessary. You can pass by reference, or (since this is in a competitive programming context where the guidelines of good code architecture can be bent) just declare them in global scope. I opted for the former here:
int findPossibleTr( const string &morse, const vector<string> &dictMorse, const vector<string> &dictWords, vector<int> &memo, int index ) {
if (memo[index] != -1) return memo[index];
int count = 0;
/* ... */
return memo[index] = count;
}
And in your initialization:
/* ... */
vector<int> memo(morse.size(), -1); // -1 here is a signal that the values are yet unknown
cout << findPossibleTr(morse, dictMorse, dictWords, memo, 0) << endl;
/* ... */
This spits out the answer 1318412525 to the above test case almost instantly.
For each of the T test cases, findPossibleTr is computed only once for each of the M suffixes of the Morse string. Each computation considers each of the N words once, with the comparison taking time linear in the length K of the word. In general, this takes O(TMNK) time which, depending on the input, might take too long. However, since matches seem to be relatively sparse in Morse code, it should run in time.
A more sophisticated approach would be to make use of a data structure such as a trie to speed up the string matching process, taking O(TMN) time in total.
Another note: it is not actually necessary for decodeToMorse to be a map. It can simply be an array or a vector of 26 strings. The string corresponding to character c is then decodeToMorse[c - 'A'].
I'm writing up my process for this situation, hope it helps.
I would first analyse the algorithm to see if it's fast enough for the problem. For example if the input of n can be as large as 10^6 and the time limit being 1 sec, then an O(n2) algorithm is not going to make it.
Then, would test against an input as 'heavy' as possible for the problem statement (max number of test cases with max input length or whatever). If it exceeds the time limit, there might be something in the code that can be optimized to get a lower constant factor. It's possible that after all the hard optimizations it's still not fast enough. In that case I would go back to step #1
After making sure the algorithm is ok, I would try to generate random inputs and try a few rounds to see if there're any peculiar cases the algorithm is yet to cover.
There are three things I'd suggest doing to improve the performance of this code.
Firstly, all the arguments to toMorse and findPossibleTr are being passed by value. This will make a copy, which for objects like std::string and std::vector will be doing memory allocations. This will be quite costly, especially for the recursive calls to findPossibleTr. To fix it, change the function declarations to take const references, like so:
string toMorse(const string& w)
int findPossibleTr( const string& morse, const vector<string>& dictMorse, const vector<string>& dictWords, int index)
Secondly, string concatenation in toMorse is doing allocations making and throwing away lots of strings. Using a std::stringstream will speed that up:
#include <sstream>
string toMorse(const string& w){
stringstream morse;
for(int i = 0; i < w.size(); i++){
morse << decodeToMorse[w[i]];
}
return morse.str();
}
Finally, we can reuse the vectors inside the loop in main, instead of destructing the old ones and creating new ones each iteration by using clear().
// ...
vector<string> dictMorse;
vector<string> dictWords;
for(size_t i = 0; i < ncases; i++){
dictMorse.clear();
dictWords.clear();
string morse;
cin >> morse;
// ...
Putting it all together on my machine gives me a 30% speed up, from 0.006s to 0.004s on your test case. Not too bad. As a bonus, if you are on an Intel platform, Intel's optimization manual says that unsigned integers are faster than signed integers, so I've switched all ints to size_ts, which also fixes up some warnings. The complete code now becomes
/*
* Multiple morse matches
* Filipe C
*/
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <map>
using namespace std;
std::map<char,string> decodeToMorse;
string toMorse(const string& w){
stringstream morse;
for(size_t i = 0; i < w.size(); i++){
morse << decodeToMorse[w[i]];
}
return morse.str();
}
size_t findPossibleTr( const string& morse, const vector<string>& dictMorse, const vector<string>& dictWords, size_t index){
size_t count = 0;
for(size_t i = 0; i < dictMorse.size(); i++){
if(morse.compare( index, dictMorse[i].size(), dictMorse[i]) == 0){
//cout<<"Found " << dictWords[i] << " on index "<<index<<endl;
if(index+dictMorse[i].size()>=morse.size()){
//cout<<"Adding one for "<< dictWords[i]<<endl;
count+=1;
//return 1;
}else{
count += findPossibleTr(morse, dictMorse, dictWords, index+dictMorse[i].size());
}
}
}
return count;
}
int main(){
size_t ncases;
cin>>ncases;
decodeToMorse['A'] = ".-";
decodeToMorse['B'] = "-...";
decodeToMorse['C'] = "-.-.";
decodeToMorse['D'] = "-..";
decodeToMorse['E'] = ".";
decodeToMorse['F'] = "..-.";
decodeToMorse['G'] = "--.";
decodeToMorse['H'] = "....";
decodeToMorse['I'] = "..";
decodeToMorse['J'] = ".---";
decodeToMorse['K'] = "-.-";
decodeToMorse['L'] = ".-..";
decodeToMorse['M'] = "--";
decodeToMorse['N'] = "-.";
decodeToMorse['O'] = "---";
decodeToMorse['P'] = ".--.";
decodeToMorse['Q'] = "--.-";
decodeToMorse['R'] = ".-.";
decodeToMorse['S'] = "...";
decodeToMorse['T'] = "-";
decodeToMorse['U'] = "..-";
decodeToMorse['V'] = "...-";
decodeToMorse['W'] = ".--";
decodeToMorse['X'] = "-..-";
decodeToMorse['Y'] = "-.--";
decodeToMorse['Z'] = "--..";
vector<string> dictMorse;
vector<string> dictWords;
for(size_t i = 0; i < ncases; i++){
dictMorse.clear();
dictWords.clear();
string morse;
cin >> morse;
size_t ndict;
cin >> ndict;
for(size_t j = 0; j < ndict; j++){
string dictw;
cin >> dictw;
dictMorse.push_back(toMorse(dictw));
dictWords.push_back(dictw);
}
cout<<findPossibleTr(morse,dictMorse, dictWords,0)<<endl;
if(ncases != 1 && i != ncases-1)
cout<<endl;
}
}

Why do I get random numbers after the input?

I'm trying to take in some input and find the number of a certain character in a string. I keep getting a weird answer when I try to take in the actual string. Why is this happening?
I'm using cout to find why I'm getting such weird numbers and it appears to be a problem with the input.
Note - This is my attempted solution to Codeforces Problem 462 B. I'm attempting to just find the number of a certain letter in the input. My friend is attempting a bubble sort method.
Input:
6 4
YJSNPI
Expected Output:
YJSNPI
4
Actual Output:
YJSNPI
1699623981
Code:
#include <iostream>
#include <string>
#include <vector>
#include <istream>
using namespace std;
int main()
{
int n, k, counting;
cin >> n >>k;
char trash;
cin.get(trash);
vector<string> cards;
string theline, name;
cin >> theline;
cout << theline << "\n";
for (int i = 0; i < n; i++){
name = theline[i];
cards.push_back(name);
}
for (int i = 0; i < n; i++){
if (cards[i] == cards[k-1]){
counting++;
}
}
int tmp = 0;
if (cards.size() != k){
tmp = k - counting;
}
counting *= k;
counting += tmp;
cout << counting;
return 0;
}
Local variables are not automatically initialized to 0. If you try to use the value of a local variable before assigning it, you get undefined behavior. You're incrementing counting without ever initializing it. Change to:
int n, k, counting = 0;
The issue is that the variable "counting" is never initialized - handy link
Basically, "counting" has some garbage value from memory after you declare it with
int counting;
Then, the first operation performed is
counting++;
And the garbage value is saved.
THE FIX:
Change
int counting;
to
int counting = 0;
NOTE: n and k are not helpful variable names. It would make understanding the code a lot easier if they had real names, but oh well.
ADDITIONALLY:
As chris mentioned above, make the compiler work for you. See comment below for good compiler flags. Don't ignore warnings!
Can't really understand what you are doing here. But I can see where you are going wrong.
int n, k, counting;
counting is uninitialized try
int n, k, counting = 0;
I get answer of (1*4 + 4 - 1) = 7 not the 4 you are expecting.
This code will always result in counting = 1, given that k is within range.
for (int i = 0; i < n; i++){
if (cards[i] == cards[k-1]){
counting++;
}
}
https://ideone.com/7Hk3ix