gpt4 book ai didi

c - Xcode调试C语言出现错误: EXC_BAD_ACCESS (code=1)

转载 作者:行者123 更新时间:2023-11-30 17:34:20 25 4
gpt4 key购买 nike

更新@2014.05.01:

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

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

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

我正在使用Xcode练习一些小型C语言程序(项目类型:Command Line Tool,语言: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 行出现错误“EXC_BAD_ACCESS (code=1, address=0x31)”:

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;
}

确实很奇怪……

我的代码有什么问题吗?有人知道原因吗? :)

最佳答案

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

您的症状与损坏的堆栈一致。寻找可能覆盖字符数组的地方。对零终止字符串的错误处理是错误的丰富来源。如果操作错误,malloc 和 free 也是如此。

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

  • 指针“ret”来自 malloc(第 46 行)。如果 malloc 失败,您会打印一条错误消息,但仍然继续使用无效指针。
  • 指针“ret_align”来自“if” block 中的malloc。如果条件不成立,则 malloc 永远不会发生,并且 ret_align 不会初始化。但该函数无论如何都会返回 ret_align 。这很容易使调用者崩溃。另外,如果条件不成立,您将无法免费返回。 (如果您尝试添加“0”和“0”,该函数会崩溃。)

我可以继续,但这应该为您提供一些开始修复代码的地方。

函数 big_add 中还有一些构建警告。看起来这两种情况都不会导致您的症状,但您应该解决它们。

关于c - Xcode调试C语言出现错误: EXC_BAD_ACCESS (code=1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23380747/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com