更新@ 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;
}
真的很奇怪......
我的代码出了什么问题?谁知道原因? :)
答案 0 :(得分:0)
我没有收到您报告的错误(当我使用Xcode 5.1.1构建时)。但你问“我的代码出了什么问题?”,这是非常开放的。
您的症状与堆叠损坏一致。查找可能会覆盖字符数组的位置。对零终止字符串的错误处理是错误的丰富来源。如果做错了,malloc也是免费的。
我们只考虑你的函数base_add。我不知道它是否“有效”,但有几件事看起来很可疑:
我可以继续,但这应该会给你一些开始修复代码的地方。
你还在函数big_add中有几个构建警告。看起来它们都不会引起你的症状,但是你应该修复它们。