我正在用C编写一个函数。我发现,当我在 gdb 中调试时,我发现在声明"result"之前,一个指针"result"与另一个指针具有相同的地址。我的部分代码:
char* stringSum(char* x, char* y){
puts(x);
puts(y);
printf("n");
int lengthx=strlen(x);
int lengthy=strlen(y);
int lengths=MIN(lengthx,lengthy);
int lengthl=MAX(lengthx,lengthy);
char* s=((lengthx<=lengthy)?x:y);
char* l=((lengthx>lengthy)?x:y);
int returnSize=MAX(lengthx, lengthy)+2;//-----I could print result now
printf("before, short is : ");puts(s);
char* result=malloc(sizeof(char)*returnSize);//-----but result is allocated now
printf("after allocate memory for result, short is: ");puts(s);//---s is changed!
result[returnSize-1]=' ';
......
}
这个函数获取两个数字的总和(字符串),以便我可以计算两个大数字的总和。在 gdb 中:我遇到了这个奇怪的问题:
我的问题在红色和黄色矩形中
(在 gdb 中调试时)在char* result=malloc(sizeof(char)*returnSize);
之前,我打印 s 和结果(所以现在还没有声明)并得到
(gdb) print s
$5 = 0x61f950 "6597242170048699800240000000000"
(gdb) print result
$6 = 0x61f950 "6597242170048699800240000000000"
我无法理解,因为未声明的指针怎么会指向现有地址?(此函数由另一个具有大量 x 和 y(字符串)的函数调用。如果我将它们更改为相对较小的值,我将始终得到正确的答案。更重要的是,如果我创建一个新的 .c 文件并且只有这个函数和 main 函数,即使值很大,我也不会再有这个问题了。
我的第二个问题是我已经打印了两次s,我发现第二次打印(在声明指针结果之后)s被更改了!(与第一个问题类似,如果我为 x 和 y 选择较小的值或创建一个新的 .c 文件,我不会遇到同样的问题。
我想我对malloc
有一些问题,但在网上搜索后,我没有找到任何有用的资源可以帮助我解决问题。我有内存管理问题吗?
你的代码至少有两个严重的问题。
第一个问题是你永远不会free
你malloc
的内容,在每次递归调用时都会产生相当大的内存泄漏。
第二个问题是你试图分配字符串,这没有你想要的效果。
这是您所做的示例(我的评论):
// allocate some memory and assign its address to abcd
char* abcd=malloc(sizeof(char)*returnSize);
// throw it away by assigning a different value to abcd
abcd=karatsuba(stringSum(a,b),stringSum(c,d));
// then assign yet another different value to abcd
abcd=stringSubstract(abcd,ac);
// and another one
abcd=stringSubstract(abcd,bd);//ab+cd
// Code below overflows, because memory abcd is pointing to is
// not the original block allocated for it (you threw it away).
// It is a block allocated and returned by stringSubstract.
// Its length is not necessarily sufficient to accommodate all
// the data you are trying to stuff in it.
int labcd=strlen(abcd);
for(i=0;i<=(ns/2-1);i++){
abcd[labcd+i]='0';
}
abcd[lac+i]=' ';
您可以通过在valgrind
下运行程序来验证是否是这种情况。您将收到错误消息,指示在神秘缩短s
之前缓冲区溢出。一切都从那里走下坡路。
为了解决此问题,您可能需要使用strcpy
而不是指针分配。修复它的另一种方法是放弃函数开头的abcd = malloc(...)
行,并使用realloc
来确保它们具有足够的大小。
此外,您肯定要修复内存泄漏。完成malloc
后,您需要为的每个变量调用free
。如果要返回malloc
ed 变量,则调用方需要在使用它后释放它。