我正在使用指向1D数组的指针数组模拟一个2d int数组。从文件中读取数据时,大小是动态的,因此我创建了一个动态分配函数(alloc2ArrInt)。它一直运行良好,直到我开始用新数据测试我的程序,现在第一个malloc有时会崩溃(分段错误?)。以下是代码的相关部分(我希望如此):
int** t_fv = NULL; // these are global
int** t_ofv = NULL;
int** b_fv = NULL;
int** b_ofv = NULL;
// assume these 2 lines are in main:
if (readFeatureVectors(&t_fv, &t_ofv, targetFilename, &trows, &tcolumns) < 0) { }
if (readFeatureVectors(&b_fv, &b_ofv, backgroundFilename, &brows, &bcolumns) < 0) { }
int readFeatureVectors(int*** fv, int*** ofv, char* fileName, int* rows, int* columns) {
// hidden code
alloc2DArrInt(fv, *rows, *columns); //&*fv
alloc2DArrInt(ofv, *rows, *columns);
// hidden code
}
void inline alloc2DArrInt(int*** array, int rows, int columns) {
int i;
*array = malloc(rows * sizeof(int*)); // sometimes crashes
if (*array != NULL ) {
for (i = 0; i < rows; i++) {
(*array)[i] = malloc(columns * sizeof(int));
if ((*array)[i] == NULL ) {
printf("Error: alloc2DArrInt - %d columns for row %dn", columns, i);
exit(1);
}
}
} else {
printf("Error: alloc2DArrInt - rowsn");
exit(1);
}
}
t_fv、t_ofv和b_fv_ofv第一个malloc时崩溃。当我切换readFeatureVectors调用的顺序时,程序在t_fv的第一个malloc处崩溃(而不是t_ofv)。
我还开发了该函数的realloc和dealloc版本,但目前它们还没有在代码中发挥作用。
我知道我应该开始使用调试器或内存检查工具,但我在使用EclipseJuno时遇到了困难。我可能会迁移到Ubuntu并尝试使用valgrind,但如果可能的话,我希望暂时避免它。
带有malloc
的行崩溃的唯一原因是堆数据结构损坏,或者array
指针无效。最有可能的结果是SIGSEGV。
否则malloc就不会崩溃,不管你传递给它什么参数。最坏的情况是它会返回NULL。
堆数据结构可能会损坏,例如由于缓冲区上溢/下溢。使用valgrind检测该或无效的array
指针条件。
我不认为您在这里展示的代码中有任何东西会导致它崩溃。我把你的程序放入eclipse,并在上面运行调试模式,它运行得很好。我使用了以下代码:
#define NULL 0
int** t_fv = NULL; // these are global
int** t_ofv = NULL;
int** b_fv = NULL;
int** b_ofv = NULL;
int main()
{
int trows = 3000;
int tcolumns = 3000;
int brows = 5000;
int bcolumns = 5000;
char targetFilename[64] = "target";
char backgroundFilename[64] = "background";
if (readFeatureVectors(&t_fv, &t_ofv, targetFilename, &trows, &tcolumns) == 1)
{printf("Worked1n"); }
if (readFeatureVectors(&b_fv, &b_ofv, backgroundFilename, &brows, &bcolumns) == 1)
{ printf("Worked2n"); }
printf("We are done nown");
}
int readFeatureVectors(int*** fv, int*** ofv, char* fileName, int* rows, int* columns) {
// hidden code
alloc2DArrInt(fv, *rows, *columns); //&*fv
alloc2DArrInt(ofv, *rows, *columns);
// hidden code
return 1;
}
void inline alloc2DArrInt(int*** array, int rows, int columns) {
int i;
*array = malloc(rows * sizeof(int*)); // sometimes crashes
if (*array != NULL ) {
for (i = 0; i < rows; i++) {
(*array)[i] = malloc(columns * sizeof(int));
if ((*array)[i] == NULL ) {
printf("Error: alloc2DArrInt - %d columns for row %dn", columns, i);
exit(1);
}
}
} else {
printf("Error: alloc2DArrInt - rowsn");
exit(1);
}
}
一步一步走,一切似乎都很顺利。我首先尝试了3x3和5x5的较小阵列,它们也很有效。然后我试了10倍大小,但我仍然没有耗尽内存。
我的第一个猜测是,您请求的行和列的大小太大,内存不足。您可以在代码中的某个地方进行繁忙的等待,并进行内存检查以查看程序占用了多少内存(在linux中是免费的,在windows中是taskmgr)。此外,您可以打印行和列,以确保您没有请求不合理大小的东西。
我认为您的//隐藏代码可能也有问题。
让Eclipse或类似的东西启动并运行会对您大有裨益。我认为,使用这样的调试工具,你会很快发现你的问题,因为你将能够找到你崩溃的确切线路,并了解当时你的内存状态。