c: difference in debug and release mode?

MinjaeKim

I'm trying to build a simple library for integer operations without bound (I know the existence of GMP, just for my self interest). I'm doing this by teaching the computer to do primary school arithmetics with char arrays. I know it is a very inefficient way, but that is what I can think of and am up to. I have succeeded to write a C code for all four +-*/ operations, but somehow only in debug mode. The code works perfectly fine both in the GDB and Visual Studio 2013 debug mode; I have tested more than enough. However, it keeps spitting out error during normal execution in release mode. I have searched a lot on this topic of having problems in release mode not detected during debug, but the solutions I found doesn't seem to fit to my case, at least within what I can see.

edit: what I mean by 'error' is that my code will execute 'goto error;', which means the calculation result was a mess, so it didn't pass my random integer calculation test given in main(). Such error happens not always but after about 10~20 successful operations during release mode. No single (any general) error occurs during debug.

Is it a very simple mistake I made in the code, a short fix of which will make everything so well? perhaps my whole code is just a crappy mess? is it some problem in my Windows 7 system? or anything else possible? I have done everything I can do myself to deal with this problem, but now I am merely clueless. Any kind help would be grateful.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define A_PLUS -1
#define A_MINUS -2
#define INT_LEN 10

typedef struct{
    int sign;
    int start;
    char *num;
} abn;

void initABN(abn *n);
void sInitABN(abn *n, char *cs);
void iInitABN(abn *n, int num);
void sReInitABN(abn *n, char *cs);
void iReInitABN(abn *n, int num);
void delABN(abn *n);
int aBigger(const abn *king, const abn *slave);
void aPlus(abn *t, const abn *a, const abn *b);
void aMinus(abn *t, const abn *a, const abn *b);
void printABN(const abn *a);
int abnToInt(const abn *a);
int iPow(int base, int exp);

int fromElse = 0;

int main(){
    srand((unsigned)time(NULL));
    printf("number of tests for each operation: ");
    int testN;
    scanf("%d", &testN);
    printf("\n");
    abn a, b;
    initABN(&a); initABN(&b);
    int i, t1, t2;
    for (i = 0; i < testN; ++i){
        t1 = rand()*(2*(rand() % 2) - 1);
        t2 = rand()*(2*(rand() % 2) - 1);
        iReInitABN(&a, t1);
        iReInitABN(&b, t2);
        printABN(&a);
        printf(" + ");
        printABN(&b);
        printf(" = ");
        aPlus(&a, &a, &b);
        printABN(&a);
        if (t1 + t2 == abnToInt(&a)){
            printf(" TRUE\n");
        }else{
            goto error;
        }
    }
    for (i = 0; i < testN; ++i){
        t1 = rand()*(2*(rand() % 2) - 1);
        t2 = rand()*(2*(rand() % 2) - 1);
        iReInitABN(&a, t1);
        iReInitABN(&b, t2);
        printABN(&a);
        printf(" - ");
        printABN(&b);
        printf(" = ");
        aMinus(&a, &a, &b);
        printABN(&a);
        if (t1 - t2 == abnToInt(&a)){
            printf(" TRUE\n");
        }else{
            goto error;
        }
    }
    delABN(&a); delABN(&b);
    printf("Test Complete!\n");
    return 0;
    error:
    printf("\nERROR\n");
    system("pause");
    return 1;
}

void initABN(abn *n){
    n->num = NULL;
}

void sInitABN(abn *n, char *cs){
    int i;
    for (i = 0; cs[i] != 0; ++i); --i;
    if (cs[0] == '-'){
        n->sign = A_MINUS;
        n->start = i - 1;
        n->num = (char*)malloc(i);
        for (; i > 0; --i){
            n->num[n->start - i + 1] = cs[i] - '0';
        }
    }else{
        n->sign = A_PLUS;
        n->start = i;
        n->num = (char*)malloc(i + 1);
        for (; i >= 0; --i){
            n->num[n->start - i] = cs[i] - '0';
        }
    }
}

void iInitABN(abn *n, int num){
    char *tempCs = (char*)malloc(INT_LEN + 1);
    sprintf(tempCs, "%d", num);
    sInitABN(n, tempCs);
    free(tempCs);
}

void sReInitABN(abn *n, char *cs){
    free(n->num);
    sInitABN(n, cs);
}

void iReInitABN(abn *n, int num){
    char *tempCs = (char*)malloc(INT_LEN + 1);
    sprintf(tempCs, "%d", num);
    sReInitABN(n, tempCs);
    free(tempCs);
}

void delABN(abn *n){
    free(n->num);
    n->num = NULL;
}

int aBigger(const abn *king, const abn *slave){
    int kingSize = king->start, slaveSize = slave->start;
    if (kingSize > slaveSize){
        return 1;
    }
    if (kingSize < slaveSize){
        return 0;
    }
    int i;
    for (i = kingSize; i >= 0; --i){
        if (king->num[i] > slave->num[i]){
            return 1;
        }
        if (king->num[i] < slave->num[i]){
            return 0;
        }
    }
    return 0;
}

void aPlus(abn *t, const abn *a, const abn *b){
    int aSign = a->sign, bSign = b->sign;
    if (!fromElse){
        if (aSign != bSign){
            fromElse = 1;
            aMinus(t, a, b);
            fromElse = 0;
            return;
        }
    }
    char *temp;
    int aStart = a->start, bStart = b->start;
    if (aStart > bStart){
        t->start = aStart + 1;
        temp = (char*)calloc(aStart + 2, 1);
    }else{
        t->start = bStart + 1;
        temp = (char*)calloc(bStart + 2, 1);
    }
    int i, j;
    for (i = 0; i <= aStart; ++i){
        temp[i] += a->num[i];
    }
    for (i = 0; i <= bStart; ++i){
        temp[i] += b->num[i];
        if (temp[i] >= 10){
            temp[i] -= 10;
            ++temp[i + 1];
            for (j = i + 1; ; ++j){
                if (temp[j] >= 10){
                    temp[j] -= 10;
                    ++temp[j + 1];
                }else{
                    break;
                }
            }
        }
    }
    if (temp[t->start] == 0){
        --t->start;
    }
    if (aSign == A_PLUS){
        t->sign = A_PLUS;
    }else{
        t->sign = A_MINUS;
    }
    free(t->num);
    t->num = temp;
}

void aMinus(abn *t, const abn *a, const abn *b){
    int aSign = a->sign, bSign = b->sign;
    if (!fromElse){
        if (aSign != bSign){
            fromElse = 1;
            aPlus(t, a, b);
            fromElse = 0;
            return;
        }
    }
    char *temp;
    int aStart = a->start, bStart = b->start;
    if (aStart > bStart){
        t->start = aStart;
        temp = (char*)calloc(aStart + 1, 1);
    }else{
        t->start = bStart;
        temp = (char*)calloc(bStart + 1, 1);
    }
    int i;
    #define MIN_CALC(A, B)\
        for (i = 0; i <= A##Start; ++i){\
            temp[i] += A->num[i];\
        }\
        for (i = 0; i <= B##Start; ++i){\
            temp[i] -= B->num[i];\
            if (temp[i] < 0){\
                temp[i] += 10;\
                temp[i + 1] -= 1;\
            }\
        }
    if (aBigger(a, b)){
        MIN_CALC(a, b);
        if (aSign == A_PLUS){
            t->sign = A_PLUS;
        }else{
            t->sign = A_MINUS;
        }
    }else{
        MIN_CALC(b, a);
        if (aSign == A_PLUS){
            t->sign = A_MINUS;
        }else{
            t->sign = A_PLUS;
        }
    }
    for (i = t->start; i > 0; --i){
        if (temp[i] == 0){
            --t->start;
        }else{
            break;
        }
    }
    free(t->num);
    t->num = temp;
}

void printABN(const abn *a){
    if (a->start == 0 && a->num[0] == 0){
        printf("0");
        return;
    }
    if (a->sign == A_MINUS){
        printf("-");
    }
    int i;
    for (i = a->start; i >= 0; --i){
        printf("%d", a->num[i]);
    }
}

int abnToInt(const abn *a){
    int i, n = 0;
    for (i = 0; i <= a->start; ++i){
        n += a->num[i]*iPow(10, i);
    }
    if (a->sign == A_MINUS){
        n *= -1;
    }
    return n;
}

int iPow(int base, int exp){
    int n = 1;
    int i;
    for (i = 0; i < exp; ++i){
        n *= base;
    }
    return n;
}
The Dark

This is caused by the fact that t and a point to the same value. When you modify a value pointed to by t it will also modify the value pointed to by a.

In your aMinus function, you use the value of a->start indirectly in the call to aBigger. However, you have already changed the value of t->start and hence a->start earlier in the function.

Here are three ways of fixing the problem:

  1. Changing the code so that the modification to t->start happens later in the function (saving the value to a new local variable and setting just before it is needed) fixes that problem. This is the best way, I think.

  2. Changing the aBigger function to take the lengths as parameters and using aStart and bstart as the values works, but still means you have changed a->start and might forget and change the code to use a->start in the future.

  3. Change the call to put the result of the addition or subtraction into a different variable. This works, but it still means your function has a potential vulnerability.

I can't explain why it works in debug mode or when debugging release mode, I'll try stepping through and seeing if I can trace it further.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Difference in relative file path: debug mode and release mode of Qt Creator

From Dev

What is the difference between .pdb files generated from Release and Debug mode?

From Dev

Visual Studio (C++) debugging in debug mode vs release mode

From Dev

C# mutex in release mode behaves different than in debug mode

From Dev

How to debug in release mode

From Dev

Debug in release mode

From Dev

Debug or Release mode with AngularJS

From Dev

How to debug in release mode

From Dev

Is there a difference in source code for release and debug compiled program? [C/C++]

From Dev

Debug and Release Mode of UWP Apps

From Dev

Debug runs fine, but not in release mode

From Dev

strtol differs in debug and release mode

From Dev

Debug and Release Mode of UWP Apps

From Dev

OpenGL renders in release mode but not debug mode

From Dev

app with Objective-C and swift code crash at launch in release mode, debug mode fine

From Dev

How to set debug false for release mode

From Java

Why is code behavior different in release & debug mode?

From Dev

Android - app icon for debug and release mode

From Dev

Different language for debug and release mode in iOS app?

From Dev

How to Determine Trial License in Debug and Release Mode

From Dev

How to set different global variable values for release and debug mode C#

From Dev

.dll reference loads properly into c# project in Debug mode but can't find namespaces in Release

From Dev

How to set different global variable values for release and debug mode C#

From Dev

Debug mode for C in eclipse

From Dev

PCLStorage/ZipArchive Difference between debug and release

From Dev

Getting correct value in Debug mode, wrong in Release mode with Serial Programing

From Dev

Multi media timer works fine in release mode but not on debug mode

From Dev

Is the running speed of a program related to Debug mode or Release mode?

From Dev

App crashes in release mode and not in debug mode - Xamarin Forms

Related Related

  1. 1

    Difference in relative file path: debug mode and release mode of Qt Creator

  2. 2

    What is the difference between .pdb files generated from Release and Debug mode?

  3. 3

    Visual Studio (C++) debugging in debug mode vs release mode

  4. 4

    C# mutex in release mode behaves different than in debug mode

  5. 5

    How to debug in release mode

  6. 6

    Debug in release mode

  7. 7

    Debug or Release mode with AngularJS

  8. 8

    How to debug in release mode

  9. 9

    Is there a difference in source code for release and debug compiled program? [C/C++]

  10. 10

    Debug and Release Mode of UWP Apps

  11. 11

    Debug runs fine, but not in release mode

  12. 12

    strtol differs in debug and release mode

  13. 13

    Debug and Release Mode of UWP Apps

  14. 14

    OpenGL renders in release mode but not debug mode

  15. 15

    app with Objective-C and swift code crash at launch in release mode, debug mode fine

  16. 16

    How to set debug false for release mode

  17. 17

    Why is code behavior different in release & debug mode?

  18. 18

    Android - app icon for debug and release mode

  19. 19

    Different language for debug and release mode in iOS app?

  20. 20

    How to Determine Trial License in Debug and Release Mode

  21. 21

    How to set different global variable values for release and debug mode C#

  22. 22

    .dll reference loads properly into c# project in Debug mode but can't find namespaces in Release

  23. 23

    How to set different global variable values for release and debug mode C#

  24. 24

    Debug mode for C in eclipse

  25. 25

    PCLStorage/ZipArchive Difference between debug and release

  26. 26

    Getting correct value in Debug mode, wrong in Release mode with Serial Programing

  27. 27

    Multi media timer works fine in release mode but not on debug mode

  28. 28

    Is the running speed of a program related to Debug mode or Release mode?

  29. 29

    App crashes in release mode and not in debug mode - Xamarin Forms

HotTag

Archive