Xcode调试C语言获取错误:EXC_BAD_ACCESS(code = 1)

时间:2014-04-30 06:03:06

标签: c xcode debugging

更新@ 2014.05.01:

我使用Xcode创建一个新项目,并将波纹管源代码复制到新项目中。然后代码按预期运行,错误就消失了。

所以我怀疑是导致错误的项目配置。但是这两个项目(有错误的项目和没有错误的项目)都使用Xcode默认配置。这个 link 是错误的项目,希望这有助于找到问题。

====================

我正在使用Xcode练习一些小型C语言程序(项目类型:命令行工具,语言:C)。

但是,当我调试程序时,我收到一个奇怪的错误。源代码如下:

//
//  main.c
//  c_review
//
//  Created by liudanking on 4/25/14.
//  Copyright (c) 2014 liudanking. All rights reserved.
//

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

char *base_add(const char *a, const char *b);
char *base_minus(const char *a, const char *b);
char *big_add(const char *a, const char *b);
char *big_minus(const char *a, const char *b);
char *big_multiply(const char *a, const char *b);
void align_big(const char *a, char *out);

void align_big(const char *a, char *out)
{
    int i;
    for (i=0; i < strlen(a); i++)
    {
        if (a[i] != '0')
        {
            if (a[i] != '\0')
            {
                strcpy(out+99-strlen(a+i), a+i);
            }
            else
            {
                strcpy(out+98, "0");
            }
            break;
        }
    }
}

char *base_add(const char *a, const char *b)
{
    char _a[100], _b[100];
    char *ret, *ret_align;
    int i, carry, sum_one;

    ret = (char*)malloc(101);
    if (ret == NULL)
    {
        printf("malloc failed");
    }
    memset(_a, '0', sizeof(_a));
    memset(_b, '0', sizeof(_b));
    memset(ret, '0', 101);
    ret[100] = '\0';

    // align a and b
    align_big(a, _a);
    align_big(b, _b);

    carry = 0;
    for (i=98; i>=0; i--)
    {

        sum_one = _a[i] - '0' + _b[i] - '0' + carry;
        carry = sum_one/10;
        sum_one = sum_one % 10;
        *(ret+i+1) = sum_one + '0';
    }

    for (i=0; i< 100; i++)
    {
        if (ret[i] != '0')
        {
            ret_align = (char*)malloc(120-i);
            if (ret[i] != '\0')
                strcpy(ret_align, ret+i);
            else
                strcpy(ret_align, "0");
            free(ret);
            break;
        }
    }

    return ret_align;
}

char *base_minus(const char *a, const char *b)
{
    char _a[100], _b[100];
    char *ret, *ret_align;
    int i, borrow, tmp;

    memset(_a, '0', sizeof(_a));
    memset(_b, '0', sizeof(_b));
    ret = (char*)malloc(100);
    memset(ret, '0', 100);
    ret[99] = '\0';

    // align a and b
    //strcpy(_a+(99-strlen(a)), a);
    //strcpy(_b+(99-strlen(b)), b);
    align_big(a, _a);
    align_big(b, _b);

    borrow = 0;
    for (i=98; i>=0; i--)
    {
        tmp = _a[i] - _b[i] - borrow;
        if (tmp >= 0)
        {
            ret[i] = tmp + '0';
            borrow = 0;
        }
        else
        {
            ret[i] = tmp + 10 + '0';
            borrow = 1;
        }
    }

    for (i=0; i< 100; i++)
    {
        if (ret[i] != '0')
        {
            ret_align = (char*)malloc(100-i);
            if (ret[i] != '\0')
                strcpy(ret_align, ret+i);
            else
                strcpy(ret_align, "0");
            free(ret);
            break;
        }
    }

    return ret_align;

}


char *big_add(const char *a, const char *b)
{
    char *ret, *p, *tp;
    char _a[100], _b[100];

    memset(_a, '0', sizeof(_a));
    memset(_b, '0', sizeof(_b));


    if (a[0] != '-' && b[0] != '-')
    {
        //        printf("%s+%s\n", a,b);
        return base_add(a, b);
    }
    printf("%d:%d:%d\n", a[0]!='-', b[0]=='-', a[0]!='-' && b[0]=='-');
    if (a[0]!='-' && b[0]=='-')
    {
        // align a and b
        printf("%d\n", strlen(a));
        strcpy(_a+99-strlen(a), a);
        strcpy(_b+(99-strlen(b)+1), b+1);
        if (strcmp(_a, _b) >= 0)
        {
            return base_minus(_a, _b);
        }
        else
        {
            p = base_minus(_b, _a);
            ret = (char*)malloc(102);
            ret[0] = '-';
            strcpy(ret+1, p);
            free(p);
            return ret;
        }
    }
    if (a[0] == '-' && b[0] != '-')
    {
        // align a and b
        strcpy(_a+(99-strlen(a)+1), a+1);
        strcpy(_b+(99-strlen(b)), b);
        if (strcmp(_a, _b) > 0)
        {
            p = base_minus(_a, _b);
            ret = (char*)malloc(102);
            ret[0] = '-';
            strcpy(ret+1, p);
            free(p);
            return ret;
        }
        else
        {
            return base_minus(_b, _a);
        }

    }
    if (a[0] == '-' && b[0] == '-')
    {
        p = base_add(a+1, b+1);
        ret = (char*)malloc(102);
        ret[0] = '-';
        strcpy(ret+1, p);
        free(p);
        return ret;
    }

    // return result
    return ret;
}

char *big_minus(const char *a, const char *b)
{
    char _b[100];

    memset(_b, '0', sizeof(_b));

    if (b[0] == '-')
    {
        return big_add(a, b+1);
    }
    else
    {
        _b[0] = '-';
        strcpy(_b+1, b);
        return big_add(a, _b);
    }

    return NULL;
}

char *big_multiply(const char *a, const char *b)
{
    char *ret, *p, *mid_ret;
    char _a[100], _b[100];
    int i, j, carry, sign, tmp;


    ret = (char*)malloc(202);
    p = (char*)malloc(202);
    memset(_a, '0', sizeof(_a));
    memset(_b, '0', sizeof(_b));
    memset(ret, '0', 202);
    ret[201]='\0';

    sign = 0;
    if (a[0] == '-')
    {
        sign++;
        strcpy(_a+99-strlen(a)+1, a+1);
    }
    else
    {
        strcpy(_a+99-strlen(a), a);
    }
    if (b[0] == '-')
    {
        sign++;
        strcpy(_b+99-strlen(b)+1, b+1);
    }
    else
    {
        strcpy(_b+99-strlen(b), b);
    }

    carry = 0;
    for (i=98; i>=0; i--)
    {
        memset(p, '0', 202);
        p[201]='\0';
        for (j=98; j>=0; j--)
        {
            tmp = (_b[i] - '0') * (_a[j] - '0') + carry;
            carry = tmp / 10;
            *(p+200+i-98 + j - 98) = tmp % 10 + '0';
        }
        mid_ret = big_add(ret, p);
        strcpy(ret, mid_ret);
        free(mid_ret);
    }

    free(p);
    return ret;
}



int main(void)
{
    char *ret, *ret2;
    char a[100], b[100], c[100], d[100];


    strcpy(a, "99");
    strcpy(b, "1001");

    //printf("%d, %s, %02x; %d, %s, %02x\n", sizeof(a)/sizeof(a[0]),a, a, sizeof(b)/sizeof(b[0]),b,b);

    ret = big_add(a, b);
    printf("%s\n", ret);
    if (ret)
        free(ret);

    strcpy(c, "99");
    strcpy(d, "1001");
    ret2 = big_minus(c, d);
    printf("%s\n", ret2);
    if (ret2)
        free(ret2);

    ret = big_multiply(a, b);
    printf("%s\n", ret);
    if (ret)
        free(ret);
    return 0;
}

直接在Xcode中运行代码会在第93行和第34行出现错误; EXC_BAD_ACCESS(代码= 1,地址= 0x31)&#34;:

memset(_a, '0', sizeof(_a)); // Thread 1: EXC_BAD_ACCESS (code=1, address=0x31)

但是,如果我使用命令 ./ my_app 在我的终端中运行已编译的应用程序,则没有错误。

我仔细检查了这条线,但未发现任何错误。

当我将函数实现移动到主函数之后的位置时(如下),错误就消失了。

//
//  main.c
//  c_review
//
//  Created by liudanking on 4/25/14.
//  Copyright (c) 2014 liudanking. All rights reserved.
//

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

char *base_add(const char *a, const char *b);
char *base_minus(const char *a, const char *b);
char *big_add(const char *a, const char *b);
char *big_minus(const char *a, const char *b);
char *big_multiply(const char *a, const char *b);
void align_big(const char *a, char *out);




int main(void)
{
    char *ret, *ret2;
    char a[100], b[100], c[100], d[100];


    strcpy(a, "99");
    strcpy(b, "1001");

    //printf("%d, %s, %02x; %d, %s, %02x\n", sizeof(a)/sizeof(a[0]),a, a, sizeof(b)/sizeof(b[0]),b,b);

    ret = big_add(a, b);
    printf("%s\n", ret);
    if (ret)
        free(ret);

    strcpy(c, "99");
    strcpy(d, "1001");
    ret2 = big_minus(c, d);
    printf("%s\n", ret2);
    if (ret2)
        free(ret2);

    ret = big_multiply(a, b);
    printf("%s\n", ret);
    if (ret)
        free(ret);
    return 0;
}

void align_big(const char *a, char *out)
{
    int i;
    for (i=0; i < strlen(a); i++)
    {
        if (a[i] != '0')
        {
            if (a[i] != '\0')
            {
                strcpy(out+99-strlen(a+i), a+i);
            }
            else
            {
                strcpy(out+98, "0");
            }
            break;
        }
    }
}

char *base_add(const char *a, const char *b)
{
    char _a[100], _b[100];
    char *ret, *ret_align;
    int i, carry, sum_one;

    ret = (char*)malloc(101);
    if (ret == NULL)
    {
        printf("malloc failed");
    }
    memset(_a, '0', sizeof(_a));
    memset(_b, '0', sizeof(_b));
    memset(ret, '0', 101);
    ret[100] = '\0';

    // align a and b
    align_big(a, _a);
    align_big(b, _b);

    carry = 0;
    for (i=98; i>=0; i--)
    {

        sum_one = _a[i] - '0' + _b[i] - '0' + carry;
        carry = sum_one/10;
        sum_one = sum_one % 10;
        *(ret+i+1) = sum_one + '0';
    }

    for (i=0; i< 100; i++)
    {
        if (ret[i] != '0')
        {
            ret_align = (char*)malloc(120-i);
            if (ret[i] != '\0')
                strcpy(ret_align, ret+i);
            else
                strcpy(ret_align, "0");
            free(ret);
            break;
        }
    }

    return ret_align;
}

char *base_minus(const char *a, const char *b)
{
    char _a[100], _b[100];
    char *ret, *ret_align;
    int i, borrow, tmp;

    memset(_a, '0', sizeof(_a));
    memset(_b, '0', sizeof(_b));
    ret = (char*)malloc(100);
    memset(ret, '0', 100);
    ret[99] = '\0';

    // align a and b
    //strcpy(_a+(99-strlen(a)), a);
    //strcpy(_b+(99-strlen(b)), b);
    align_big(a, _a);
    align_big(b, _b);

    borrow = 0;
    for (i=98; i>=0; i--)
    {
        tmp = _a[i] - _b[i] - borrow;
        if (tmp >= 0)
        {
            ret[i] = tmp + '0';
            borrow = 0;
        }
        else
        {
            ret[i] = tmp + 10 + '0';
            borrow = 1;
        }
    }

    for (i=0; i< 100; i++)
    {
        if (ret[i] != '0')
        {
            ret_align = (char*)malloc(100-i);
            if (ret[i] != '\0')
                strcpy(ret_align, ret+i);
            else
                strcpy(ret_align, "0");
            free(ret);
            break;
        }
    }

    return ret_align;

}


char *big_add(const char *a, const char *b)
{
    char *ret, *p, *tp;
    char _a[100], _b[100];

    memset(_a, '0', sizeof(_a));
    memset(_b, '0', sizeof(_b));


    if (a[0] != '-' && b[0] != '-')
    {
        //        printf("%s+%s\n", a,b);
        return base_add(a, b);
    }
    printf("%d:%d:%d\n", a[0]!='-', b[0]=='-', a[0]!='-' && b[0]=='-');
    if (a[0]!='-' && b[0]=='-')
    {
        // align a and b
        printf("%d\n", strlen(a));
        strcpy(_a+99-strlen(a), a);
        strcpy(_b+(99-strlen(b)+1), b+1);
        if (strcmp(_a, _b) >= 0)
        {
            return base_minus(_a, _b);
        }
        else
        {
            p = base_minus(_b, _a);
            ret = (char*)malloc(102);
            ret[0] = '-';
            strcpy(ret+1, p);
            free(p);
            return ret;
        }
    }
    if (a[0] == '-' && b[0] != '-')
    {
        // align a and b
        strcpy(_a+(99-strlen(a)+1), a+1);
        strcpy(_b+(99-strlen(b)), b);
        if (strcmp(_a, _b) > 0)
        {
            p = base_minus(_a, _b);
            ret = (char*)malloc(102);
            ret[0] = '-';
            strcpy(ret+1, p);
            free(p);
            return ret;
        }
        else
        {
            return base_minus(_b, _a);
        }

    }
    if (a[0] == '-' && b[0] == '-')
    {
        p = base_add(a+1, b+1);
        ret = (char*)malloc(102);
        ret[0] = '-';
        strcpy(ret+1, p);
        free(p);
        return ret;
    }

    // return result
    return ret;
}

char *big_minus(const char *a, const char *b)
{
    char _b[100];

    memset(_b, '0', sizeof(_b));

    if (b[0] == '-')
    {
        return big_add(a, b+1);
    }
    else
    {
        _b[0] = '-';
        strcpy(_b+1, b);
        return big_add(a, _b);
    }

    return NULL;
}

char *big_multiply(const char *a, const char *b)
{
    char *ret, *p, *mid_ret;
    char _a[100], _b[100];
    int i, j, carry, sign, tmp;


    ret = (char*)malloc(202);
    p = (char*)malloc(202);
    memset(_a, '0', sizeof(_a));
    memset(_b, '0', sizeof(_b));
    memset(ret, '0', 202);
    ret[201]='\0';

    sign = 0;
    if (a[0] == '-')
    {
        sign++;
        strcpy(_a+99-strlen(a)+1, a+1);
    }
    else
    {
        strcpy(_a+99-strlen(a), a);
    }
    if (b[0] == '-')
    {
        sign++;
        strcpy(_b+99-strlen(b)+1, b+1);
    }
    else
    {
        strcpy(_b+99-strlen(b), b);
    }

    carry = 0;
    for (i=98; i>=0; i--)
    {
        memset(p, '0', 202);
        p[201]='\0';
        for (j=98; j>=0; j--)
        {
            tmp = (_b[i] - '0') * (_a[j] - '0') + carry;
            carry = tmp / 10;
            *(p+200+i-98 + j - 98) = tmp % 10 + '0';
        }
        mid_ret = big_add(ret, p);
        strcpy(ret, mid_ret);
        free(mid_ret);
    }

    free(p);
    return ret;
}

真的很奇怪......

我的代码出了什么问题?谁知道原因? :)

1 个答案:

答案 0 :(得分:0)

我没有收到您报告的错误(当我使用Xcode 5.1.1构建时)。但你问“我的代码出了什么问题?”,这是非常开放的。

您的症状与堆叠损坏一致。查找可能会覆盖字符数组的位置。对零终止字符串的错误处理是错误的丰富来源。如果做错了,malloc也是免费的。

我们只考虑你的函数base_add。我不知道它是否“有效”,但有几件事看起来很可疑:

  • 指针“ret”来自malloc(第46行)。如果malloc失败,则打印错误消息,然后继续使用无效指针。
  • 指针“ret_align”来自“if”块中的malloc。如果条件不为真,则malloc永远不会发生,并且不会初始化ret_align。但无论如何,该函数返回ret_align。这很容易使调用者崩溃。此外,如果条件不正确,则不要自由撤销。 (如果您尝试添加“0”和“0”,则函数崩溃。)

我可以继续,但这应该会给你一些开始修复代码的地方。

你还在函数big_add中有几个构建警告。看起来它们都不会引起你的症状,但是你应该修复它们。