【发布时间】:2015-12-03 12:58:22
【问题描述】:
我用 C 编写了一个程序。问题是当我在 Linux/Unix 环境中编译这个程序时,我遇到了段错误。但是当我在 Windows 中使用 minGW 编译它时它工作正常。基本上在程序中我有一个多维数组。当我在 Linux/Unix 中的 gdb 中编译和调试时,我随机丢失了一行多维数组。当我尝试访问该行中的每一列时,突然无法访问所有列。我的整排都迷路了。
错误:程序收到信号 SIGSEGV,分段错误。
注意:isItDone()、oneToTwo() 和 checkAroundTwo() 很可能不是问题所在。我尝试在没有它们的情况下运行程序,但它仍然显示错误。
代码:
int main( int argc, char *argv[] ){
FILE * output;
output = fopen("output.txt", "w");
srand(time(NULL));
int size = 0; // Resetting before taking arguments
int evaltime = 0; // Resetting before taking arguments
int rand1, rand2;
int counter, counter2, counter3;
if(argc == 3){
size = atoi(argv[1]);
evaltime = atoi(argv[2]);
}
else{
return 0;
}
double *evaltimes = (double*)calloc(evaltime , sizeof(double)); // The array of the results we got.
for(counter2 = 0; counter2 < evaltime; counter2++){
int cellnumbers = 0;
int **ground = (int**)malloc(size * sizeof(int)); //Mallocating for every iteration
for(counter = 0; counter < size; counter++){
ground[counter] = (int*)calloc(size, sizeof(int)); // Initializing all the 0.
}
while(!isItDone(ground, size)){ // It's finished when last row is 2.
rand1 = rand() % size;
rand2 = rand() % size; // Take two random numbers for picking in array limit.
printf("%d %d\n", rand1, rand2);
if(rand1 == 0){ // Is it a top cell
if(ground[rand1][rand2] == 0){
ground[rand1][rand2] = 2;
cellnumbers++; // Increment when a cell is picked.
}
}
else{
if(ground[rand1][rand2] == 1 || ground[rand1][rand2] == 2) // The cell is already opened
continue;
else{
ground[rand1][rand2] = 1; // Defaulting to 1 before control
cellnumbers++;
oneTotwo(ground, size, rand1, rand2);
}
}
}
if(counter2 == evaltime - 1){ // Printing the last variation
for(counter3 = 0; counter3 < size; counter3++){
for(counter = 0; counter < size; counter++){
fprintf(output, "%d ",ground[counter3][counter]);
}
fprintf(output, "\n");
}
}
evaltimes[counter2] = (double)cellnumbers / (double)(size*size);
for(counter = 0; counter < size; counter++)
free(ground[counter]);
free(ground);
}
double meany = mean(evaltimes, evaltime);
double stddeviation = stddev(evaltimes, evaltime, meany);
fprintf(output, "mean() = %f \n", meany);
fprintf(output, "stddev() = %f",stddeviation);
fclose(output);
return 0;
}
我认为错误很可能在于 main 但这是我的功能。
int isItDone(int **p, int size){
int counter;
for(counter = 0; counter < size; counter++){
if(p[size - 1][counter] == 2 && (p + size - 1) != 0)
return 1;
}
return 0;
}
void oneTotwo(int **p, int size, int rand1, int rand2){
//Checking the Upper Cells
if(rand1 < size - 1){ // Making sure no control if it is the last cell.
if(p[rand1 + 1][rand2] == 2){
p[rand1][rand2] = 2;
checkAroundTwo(p, size, rand1, rand2);
}
}
if(rand1 > 0){
if(p[rand1 - 1][rand2] == 2){
p[rand1][rand2] = 2;
checkAroundTwo(p, size, rand1, rand2);
}
}
if(rand2 < size - 1){
if(p[rand1][rand2 + 1] == 2){
p[rand1][rand2] = 2;
checkAroundTwo(p, size, rand1, rand2);
}
}
if(rand2 > 0){
if(p[rand1][rand2 - 1] == 2){
p[rand1][rand2] = 2;
checkAroundTwo(p, size, rand1, rand2);
}
}
}
void checkAroundTwo(int **p, int size, int rand1, int rand2){
if(rand1 < size - 1){
if(p[rand1 + 1][rand2] == 1){
p[rand1 + 1][rand2] = 2;
checkAroundTwo(p, size, rand1 + 1, rand2);
}
}
if(rand1 > 0){
if(p[rand1 - 1][rand2] == 1){
p[rand1 - 1][rand2] = 2;
checkAroundTwo(p, size, rand1 - 1, rand2);
}
}
if(rand2 < size - 1){
if(p[rand1][rand2 + 1] == 1){
p[rand1][rand2 + 1] = 2;
checkAroundTwo(p, size, rand1, rand2 + 1);
}
}
if(rand2 > 0){
if(p[rand1][rand2 - 1] == 1){
p[rand1][rand2 - 1] = 2;
checkAroundTwo(p, size, rand1, rand2 - 1);
}
}
}
double mean(double *p, int size){
double sum = 0.0000000;
int counter;
for(counter = 0; counter < size; counter++)
sum += p[counter];
return sum / (double)(size);
}
double stddev(double *p, int size, double mean){
double sum = 0.0000000;
int counter;
for(counter = 0; counter < size; counter++)
sum += sqr(((double)p[counter] - mean));
return sqrt(sum / (double)(size - 1));
}
double sqr(double x){
return x*x;
}
double sqrt(double x){
int counter = 0;
while(sqr(counter) < x){
counter++;
}
double s = counter;
for(counter = 0; counter < 50; counter++){
s = (double)1/2 * (double)(s + x/s);
}
return s;
}
让我们假设 int array[10][10] 更奇怪的事情是,在 gdb 中,例如当我丢失 array[5] 行时,我尝试从它之前的行访问它。例如数组[4][10]。当我这样做时“数组[4][10] = 49”。为什么是这样? Rest is (array[4][12], array[4][13] etc.) 是我指定的 0。为什么突然从第 4 行获得的第 5 行的第一个元素变成 49 ?我不明白。
【问题讨论】:
-
阅读undefined behavior。使用
gcc -Wall -Wextra -g编译您的代码。使用valgrind 和gdb调试器 -
请注意,当您将内存分配给二维数组时,您实际上需要最初分配内存
sizeof(int*)而不仅仅是sizeof(int),因此您应该更改:int **ground = (int**)malloc(size * sizeof(int));到int **ground = (int**)malloc(size * sizeof(int*)); -
@MPI_What 非常感谢!这实际上解决了我的问题。我怎么会错过呢?!该程序运行良好,符合预期,感谢您的帮助。
-
没问题!不知道会不会。在这种情况下,我会将其写成实际答案,如果您想帮助未来的用户,您可以接受它:)。
-
OT:只是不要转换
malloc()的结果,因为它在 C 中不需要也不推荐。
标签: c arrays linux gcc segmentation-fault