我有一个c函数,它使用malloc生成一个int数组。它运行得很好,我认为它做什么并不重要,因为问题实际上与此无关。(在这种情况下,它计算给定int和基数的数字)。我需要这个数组临时在一个函数中,它可能是一个。。。(你知道了,这个函数可以用几次),在返回之前,我想免费运行,但它不起作用。这是一个测试代码(它使用qsort将int数组排序为二进制表示中的1的数量(是的,我知道本可以更直接地计算结果,但重点是我在尝试免费运行时遇到的问题(这里是函数ones中的注释)):
#include <stdio.h>
#include <stdlib.h>
int values[] = { 88, 56, 100, 2, 25, 0, 15};
int * baseString(int u, int base);
int abs(int a);
int ones(int a);
int cmpfunc (const void * a, const void * b)
{
return ones(*(int*)a)>ones(*(int*)b);
}
int main()
{
int n;
printf("Before sorting the list is: n");
for( n = 0 ; n < 7; n++ )
{
printf("%d ", values[n]);
}
qsort(values, 7, sizeof(int), cmpfunc);
printf("nAfter sorting the list is: n");
for( n = 0 ; n < 7; n++ )
{
printf("%d (Ones=%d) ", values[n], ones(values[n]));
}
printf("n");
return(0);
}
int abs(int a){
return (a<0)? a*-1:a;
}
int* baseString(int u, int base){
int* r=malloc(sizeof(int));
r[0]=base;
r[1]=1;
if(base<2){
r[2]=-1;
return r;
}
int negativ=0;
if(u<0){
u=abs(u);
negativ=1;
}
int i=2;
do{
int ur=u%base;
r[i]=ur;
u/=base;
i++;
}while(u>0);
r[1]=i-1;
if(negativ){
r[1]=-r[1];
}
return r;
}
int ones(int a){
int* ai=baseString(a, 2);
int a1=1;
for(int i=2; i<abs(ai[1]); i++){
if(ai[i]==1){
a1++;
}
}
if(!a){
a1=0;
}
//free(ai);
return a1;
}
PS:我很确定这个线程在某个地方是重复的,但我没有找到它。
问题的一部分实际上很简单。
在baseString()
函数中,前三行是
int* r=malloc(sizeof(int));
r[0]=base;
r[1]=1;
malloc()
动态地分配单个int
或具有一个元素的阵列。CCD_ 4修改具有一个元素的该阵列的第二个元素。
其结果是未定义的行为。从这样的数组末尾运行的一个常见症状是损坏程序中的内存,例如malloc()
和free()
内部用于跟踪分配和释放的内存的内存。这可以解释你的问题。
确保分配了所需的元素数量。例如,如果需要10个元素,则malloc(10*sizeof(int))
。您需要计算出所需的数量,因为动态数组不会神奇地增长到所需的元素数量。
我还没有看得更远,所以可能还有其他问题。但这张照片很刺眼。
检查malloc()
是否真的成功也是一个好主意。如果失败,则返回NULL
。
这里的关键问题出现在ABW(数组边界写入)上。在baseString
函数中,您实际上是在分配相当于1个整数大小的内存,但却试图像r[1],r[2], r[i]
等中的数组一样访问它,这导致写入技术上不属于您的内存。
代码中的代码片段对应于
int* r=malloc(sizeof(int));
r[0]=base;
r[1]=1; //ABW here
if(base<2){
r[2]=-1; //ABW here
return r;
}
do{
int ur=u%base;
r[i]=ur; //ABW here
u/=base;
i++;
}while(u>0);
这可能会在代码的任何时间点导致未定义的行为。在您的情况下,它似乎影响了free
,因为内存覆盖可能会扰乱malloc和free实现的内部记账数据。