我在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]='\0';
......
}
此函数获取两个数字的总和(以字符串形式),以便我可以计算两个大数的总和。在gdb中:我遇到了这个奇怪的问题:
My problems are in red and yellow rectangles
(在gdb中调试时)char* result=malloc(sizeof(char)*returnSize);
之前我打印s和结果(现在它还没有被声明)并得到了
(gdb) print s
$5 = 0x61f950 "6597242170048699800240000000000"
(gdb) print result
$6 = 0x61f950 "6597242170048699800240000000000"
我无法理解,因为未声明的指针如何指向现有地址? (此函数由具有大量x和y(在字符串中)的另一个函数调用。如果我将它们更改为相对较小的值,我将始终得到正确的答案。而且,如果我创建一个新的.c文件并且只有这个功能和主要功能,即使价值很大,我也不会再遇到这个问题了。)
我的第二个问题是我已经打印了两次,我发现第二次打印(在声明指针结果后)s被更改了! (与第一个问题类似,如果我为x和y选择较小的值或创建一个新的.c文件,我将不会遇到同样的问题。)
我想我在使用malloc
时遇到了一些问题,但在线搜索后我发现没有任何有用的资源可以帮助我解决问题。我有关于内存管理的问题吗?
答案 0 :(得分:1)
您的代码至少存在两个严重问题。
第一个问题是你永远不会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]='\0';
您可以通过在valgrind
下运行程序来验证是否属于这种情况。在s
神秘缩短之前,您将收到指示缓冲区溢出的错误消息。这一切都从那里走下坡路。
为了解决问题,您可能希望使用strcpy
而不是指针赋值。修复它的另一种方法是放弃函数开头的abcd = malloc(...)
行,并使用realloc
确保分配的大小足够。
此外,您肯定想要修复内存泄漏。完成后,您需要为free
的每个变量致电malloc
。如果您要返回malloc
ed变量,则调用者需要在使用它后将其释放。