根据我之前的问题(非常感谢 Jonathan Leffler),我编辑了我的代码(后两个代码块),但我遇到了一个相当奇怪的问题。
以下是不可预知的中断...
void free_array(array_info *A)
{
int i;
for(i = 0; i < (A->height); ++i)
{
printf("About to free: %x\n", A->dat_ptr[i]);//for debugging purposes
free(A->dat_ptr[i]);
printf("Freed row %i\n", i);//for debugging purposes
}
free(A->dat_ptr);
}
我最初create_array
直接测试free_array
,它与相当大的数组(10 ^ 8)完美配合。但是,当我在两者之间进行计算然后尝试free()
使用数组时,我得到了访问冲突异常 (c00000005)。当我调试它时,我注意到如果我在“free_array”循环中有一个断点并单独执行每一行,程序每次都会完美执行。但是,编译后的代码永远不会自己运行超过我的第二个数组的第 6 行。我关闭了编译器中的所有优化,执行时仍然出现错误。
附加信息
typedef struct {
int height;
int width;
int bottom;//position of the bottom tube/slice boundary
unsigned int** dat_ptr;//a pointer to a 2d array
} array_info;
dat_ptr
现在是一个适当的 2D 指针。创建要放入结构中的数组的create_array
函数是(我已经剥离了 NULL 检查的可读性):
int create_array(array_info *A)
{
int i;
unsigned int **array = malloc(sizeof(*array) * A->height);
for (i = 0; i < A->height; ++i)
{
array[i] = malloc(sizeof(**array) * A->width);
}
A->dat_ptr = array;
return 0;
}
此功能完全按预期工作。
更多附加信息
在 Jonathan、Chris 和 rharrison33 的回复之后添加
非常感谢乔纳森,在你的每一篇文章中,我都发现了很多关于编程的知识:)我终于找到了罪魁祸首。导致异常的代码如下:
void fill_number(array_info* array, int value, int x1, int y1, int x2, int y2)//fills a rectangular part of the array with `value`
{
int i, j;
for(i=y1 ; ((i<=y2)&&(i<array->height)) ; i++)//start seeding the values by row (as in vertically)
{
for(j=x1 ; ((i<=x2)&&(i<array->width)) ; j++)//seed the values by columns (as in horizontally)
{
array->dat_ptr[i][j]=value;
}
}
}
并且((i<=x2)&&(i<=array->width))
没有像我预期的那样被评估(克里斯多德,你是对的)。我认为它会按该顺序评估这两个条件,或者如果其中一个为“FALSE”则停止,而与它们的顺序无关。然而,事实证明它不是那样工作的,它只是拒绝(i<array->width)
正确评估零件。另外,我认为它会在尝试访问数组范围之外的内存时触发异常,但事实并非如此。反正,
我将代码更改为:
void fill_number(array_info* array, int value, int x1, int y1,
int x2, int y2)
{
int i, j;
if(y1>=array->height){ y1=array->height-1;}
if(y2>=array->height){ y1=array->height-1;}
if(x1>=array->width) { x2=array->width-1;}
if(x2>=array->width) { x2=array->width-1;}
for(i=y1 ; i<=y2 ; i++)//start seeding the values by row
{
for(j=x1 ; j<=x2 ; j++)//seed the values by column
{
array->dat_ptr[i][j]=value;
}
}
}
现在它可以工作了。s块在if()
那里,因为与其他代码相比,我不会经常调用该函数,并且我需要一种视觉方式来提醒我检查在那里。
再次感谢 Jonathan Leffler、Chris Dodd 和 rharrison33 :)