1

Below is my function. It runs correctly once, then when it is called a second time it causes an error telling me "double free or corruption". I tried adding the +1 inside the malloc() as other posts have suggested, even though I am not storing null-terminated strings but arrays of integers. It did not help.

I am very confused at this point. I don't understand why at the end of the function the pointer that was free()'d doesn't go out of scope, or if it does, then how it can be considered a double-free when I malloc()'d after free()ing it the last time it was used.

int getCount(int number) {

    int totalUniqueDigits = 0;

    bool* allDigits = (bool*)malloc(10 * sizeof(bool));

    do {
        int currentDigit = number % 10;
        number /= 10;
        allDigits[currentDigit] = true;
    } while (number > 0);

    for (int i = 0; i < 10; i += 2) {   
        if (allDigits[i] == true) {     
            totalUniqueDigits++;        
        }
    }

    free(allDigits);    /*This is where the problem is, but only the second time the function is called. */ 
    allDigits = NULL;

    return totalUniqueDigits; 
}
Patrick
  • 33
  • 4
  • I can also share the function that is calling this one if needed, but it is much longer and I'm not sure of its relevance. – Patrick Jan 27 '18 at 06:08
  • This is all there is in the function? what was the input `number`? Also you are comparing uninitialized value - which is UB. You are doing `i+=2` - why so? – user2736738 Jan 27 '18 at 06:11
  • If `number` is negative, then `currentDigit` will be negative also, and you'll write out of bounds. On most systems, writing to `allDigits[-1]` would overwrite information used to manage memory. – Cris Luengo Jan 27 '18 at 06:14
  • HA YES IT IS THE NEGATIVE VALUE I MUST ADD AN ABSOLUTE VALUE FUNCTION IN THERE! YES! – Patrick Jan 27 '18 at 06:20
  • @CrisLuengo.: If number is negativem result will be negative also...`-10%10=0` not always. But in case neg its problem as you mentioned. – user2736738 Jan 27 '18 at 06:22
  • It was exactly that. In the sample data instuctor provided, the second value was negative. I feel stupid, but thanks very much Cris Luengo :) – Patrick Jan 27 '18 at 06:23
  • Please add an answer to this interesting question (doing it yourself is fine). It gets it out of the list of unanswered questions. (Or maybe you, @CrisLuengo.) – Yunnosch Jan 27 '18 at 06:28
  • Patrick, please change language from C to C++. C doesn't have built-in boolean types. It won't compile in gcc standalone. – iantonuk Jan 27 '18 at 06:37
  • I have included #include "stdbool.h" in another part of the program, does this change things BedBad? – Patrick Jan 27 '18 at 06:43
  • @bedbad: `` defines macros `bool`, `true` and `false`: http://en.cppreference.com/w/c/types/boolean – Cris Luengo Jan 27 '18 at 06:51
  • https://stackoverflow.com/a/1608321/5059838 No it's not. Please check the standard. If you want to change tag to c99 or c11 you ask that too, but its different languages from C. – iantonuk Jan 27 '18 at 06:57
  • @bedbad C99 **is** C. "C" doesn't mean K&R C, you're not complaining about the function signature either. C evolves, just like any other language. – Cris Luengo Jan 27 '18 at 14:14

3 Answers3

0

The array index was not being checked for negative values. Case Closed. Thanks Cris.

Patrick
  • 33
  • 4
0

If number is negative, then

currentDigit = number % 10;

will be negative also (or zero if divisible by 10). This is a somewhat awkward (IMO) definition of the modulus operator.

If currentDigit is negative, then

allDigits[currentDigit] = true;

will write out of bounds. On most systems, writing to allDigits[-1] would overwrite information used to manage memory. This might not directly crash your program, but using malloc later could have that effect.

The solution of course is to either use abs or add 10 to currentDigit if it is negative.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
0

The Code you have posted runs with no error for all positive integers. It is C++ code, not C code. If it's a C code you need to show declaration of "bool", "true" and "false", otherwise there is no mistake inside of the provided function, execution wise.

Here's a full C++ program to test it.

#include <iostream>
using namespace std;


int getTotalUniqueEvenDigitCount(int number) {

    int totalUniqueDigits = 0;

    bool* allDigits = (bool*)malloc(10 * sizeof(bool));

    do {
        int currentDigit = number % 10;
        number /= 10;
        allDigits[currentDigit] = true;
    } while (number > 0);

    for (int i = 0; i < 10; i += 2) {   
        if (allDigits[i] == true) {     
            totalUniqueDigits++;        
        }
    }

    free(allDigits);    /*This is where the problem is, but only the second time the function is called. */ 
    allDigits = NULL;

    return totalUniqueDigits; 
}


int main(int argc, char ** argv){
  cout << getTotalUniqueEvenDigitCount(stoi(argv[1]));
  return 0;
}

Test it as

$<progname> number
iantonuk
  • 1,178
  • 8
  • 28
  • Yes, I know. I just didn't know negative integers is in a domain. Calling [] with a negative number is obviously an error. – iantonuk Jan 27 '18 at 06:48