本文介绍了C程序用cygwin编译在Windows中工作,在Linux下分段故障。是cygwin GCC'坏'?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的Programming 102类,我们要求提供在Linux下编译和运行的C代码。我没有足够的空间在我的硬盘驱动器上安装Linux和Windows,所以我使用cygwin编译我的程序。



我最近的程序在cygwin下编译和运行良好。它在Linux下编译良好,但是中途执行会产生分段错误。我向向我们提供课程的研究生解释了这一点,他说cygwin的GCC版本允许编译和执行sloppier代码。



通过google没有结论。我发现一个线程说,在Linux下的seg故障的原因是内存泄漏。为什么这不会影响cygwin版本?



我会使用大学的电脑,但我不能使用Subversion,这将大大阻碍我的努力。 (我是新的编码,通常需要能够恢复到X修订前)。



cygwin的版本的GCC真的更它编译的代码?如果是,在编码时是否有明显的问题需要注意?有没有其他方法可以编写将在Linux下运行的代码?



编辑


$ b b

感谢您的回复。我在我的原始文章不够明确:我的代码中有一个错误是给了我很多(我是一个新的编程,真的绿色,当谈到C,毕竟)。我的TA暗示cygwin的GCC是一个不那么可靠的编译器 - 允许很多的代码运行 - 比在GNU / Linux下找到的代码。我发现这个奇怪的,所以在互联网上搜索,但实际上找不到任何参考的事实。



更多的责怪编译器与我的代码,我想知道什么原因可能是程序在Windows下运行和崩溃在Linux下。回复:在Windows / Linux下不同的内存管理器和堆/堆栈布局说明了这一点。



cygwin的GCC的结论是 GNU / Linux,它是底层操作系统/纯粹的运气,我的多虫程序运行在一个而不是其他几乎是正确的?



关于发布源代码,这是一个家庭作业,所以我更喜欢自己找到问题:)



编辑2



我接受了jalf的回答,因为它谈到了什么使程序在Windows下运行,而不是在Linux下运行,这是我真正想知道的。感谢所有其他贡献的人,他们都是非常有趣和翔实的回复。



当我发现问题,并修复它,我会上传一个zip文件与所有)



编辑3 这是非工作版本的源代码,如果有人想知道我到底做了什么? p>

对于那些有兴趣查看代码的人,我发现了问题,这确实是由于指针。我试图从一个函数返回一个指针。我试图返回的指针正在函数中声明,所以一旦函数执行就被销毁。有问题的代码在第22-24行被注释掉。



请随意嘲笑我的代码。

  / ** 
*返回基于当前坐标的有效搜索数组
* /
void define_searches(int row,int col,int last_row,int last_col,int * active_search){
//定义坐标类别和相关的有效搜索方向
int Library0 [] = {2,3,4,-1};
int Library1 [] = {4,5,6,-1};
int Library2 [] = {2,3,4,5,6,-1};
int Library3 [] = {0,1,2,3,4,5,6,7,-1};
int Library4 [] = {0,1,2,-1};
int Library5 [] = {0,6,7,-1};
int Library6 [] = {0,1,2,6,7,-1};
int Library7 [] = {0,1,2,3,4,-1};
int Library8 [] = {0,4,5,6,7,-1};

int * Library [] = {
Library0,Library1,Library2,
Library3,Library4,Library5,
Library6,Library7,Library8,
} ;

//声明(并分配内存给)要返回的有效搜索方向数组
// int * active_search;
// active_search =(int *)malloc(SEARCH_DIRECTIONS * sizeof(int));


//根据当前坐标确定哪个是正确的搜索方向数组
//左上角
int i = 0;
if(row == 0& col == 0){
while(Library [0] [i]!= -1){
active_search [i] = Library [ 0] [i];
i ++;
}
}
//右上角
else if(row == 0& col == last_col){
while(Library [1] [i]!= -1){
active_search [i] = Library [1] [i];
i ++;
}
}
//第一行的非边列
else if(row == 0&&(col!= 0 || col!= last_col) ){
while(Library [2] [i]!= -1){
active_search [i] = Library [2] [i]
i ++;
}
}
//非边缘坐标(无边缘列或行)
else if(row!= 0& row!= last_row&& col [= 0& col!= last_col){
while(Library [3] [i]!= -1){
active_search [i] = Library [3] [i]
i ++;
}
}
//左下角
else if(row == last_row& col == 0){
while(Library [4] [i]!= -1){
active_search [i] = Library [4] [i];
i ++;
}
}
//右下角
else if(row == last_row& col == last_col){
while(Library [5] [i]!= -1){
active_search [i] = Library [5] [i];
i ++;
}
}
//最后一行的非边缘列
else if(row == last_row&(col!= 0 || col!= last_col) ){
while(Library [6] [i]!= -1){
active_search [i] = Library [6] [i]
i ++;
}
}
//第一列的非边缘行
else if((row!= 0 || row!= last_row)& col == 0 ){
while(Library [7] [i]!= -1){
active_search [i] = Library [7] [i]
i ++;
}
}
//最后一列的非边缘行
else if((row!= 0 || row!= last_row)& col == last_col ){
while(Library [8] [i]!= -1){
active_search [i] = Library [8] [i]
i ++;
}
}
active_search [i] = -1;
}


解决方案

可能想在这里发布您的一些代码,即使这不是你的问题的真正点。它可能仍然是一个很好的学习经验,让每个人都在戳你的代码,看看他们是否能找到导致segfault的原因。



但是,问题是,是如此多的平台依赖,以及基本上随机的因素影响C程序。虚拟内存意味着有时 ,访问未分配的内存似乎工作,因为您碰到了一个页面的未使用的部分,在某些较早的点分配。其他时候,它会segfault,因为你打到一个没有分配给你的进程的页面。这是真的不可能预测。它取决于您的内存分配的位置,是在页面的边缘还是在中间?这取决于操作系统和内存管理器,以及哪些页面已经分配到目前为止,以及......你的想法。不同的编译器,不同版本的相同编译器,不同的操作系统,不同的软件,驱动程序或硬件安装在系统上,任何东西都可以改变,当你访问未分配的内存时是否会出现segfault。



至于TA声称cygwin更轻松,这是垃圾,一个简单的原因。
编译器都没有遇到错误!如果原生GCC编译器真的不那么松懈,它会给你在编译时的错误。 Segfaults不是由编译器生成的。编译器没有多少可以确保你得到一个segfault,而不是一个似乎工作的程序。


For my Programming 102 class we are asked to deliver C code that compiles and runs under Linux. I don't have enough spare space on my hard drive to install Linux alongside Windows, and so I use cygwin to compile my programs.

The most recent program I had to give in compiles and runs fine under cygwin. It compiles fine under Linux, but half-way through execution produces a segmentation fault. I explained this to the grad student who gives us class and he said that cygwin's version of GCC allows for sloppier code to be compiled and executed.

The few references I have found via google haven't been conclusive. One thread I found said that the cause for the seg fault under Linux is a memory leak. Why would this not affect the cygwin version?

I would use the University's computers, but I can't use Subversion on them which would significantly hinder my efforts. (I'm new to coding and often need to be able to be able to revert to X revisions ago).

Is cygwin's version of GCC really more 'lax' with the code it compiles? If so, are there any obvious issues to look out for when coding? Are there any alternatives for being able to write code that will run under Linux?

Edit

Thanks for the replies. I wasn't explicit enough in my original post: that there is a bug in my code was pretty much a given for me (I am quite new to programming, and really green when it comes to C, after all). My TA implied cygwin's GCC is a less reliable compiler -allowing for much sloppier code to run- than the one found under GNU/Linux. I found this strange and so had a search on the internet, but couldn't really find any references to that fact.

More than blaming the compiler vs. my code, I was wondering what the reason could be for the program to run under Windows and crash under Linux. The replies re: different memory managers and heap/stack layout under Windows/Linux were illustrating in that regard.

Would the conclusion that cygwin's GCC is just as 'good' as GNU/Linux', and it's the underlying operating systems/sheer luck that my buggy program runs under one and not the other be pretty much correct?

Regarding posting the source code, it's a homework assignment so I'd prefer to find the issue myself if at all possible :)

Edit 2

I've accepted jalf's answer as it talks about what makes the program run under Windows and not under Linux, which was what I really wanted to know. Thanks to everyone else who contributed, they were all very interesting and informative replies.

When I've found the issue and fixed it I'll upload a zip file with all the source code of this non-working version, in case anyone is curious to see what the hell I did :)

Edit 3

For those interested in seeing the code, I found the problem, and it was indeed due to pointers. I was trying to return a pointer from a function. The pointer I was trying to return was being declared inside the function and so was being destroyed once the function executed. Problematic code is commented out on lines 22-24.

Feel free to ridicule my code.

/**
*  Returns array of valid searches based on current coordinate
*/
void determine_searches(int row, int col, int last_row, int last_col, int *active_search){
    // define coordinate categories and related valid search directions
    int Library0[] = {2, 3, 4, -1};
    int Library1[] = {4, 5, 6, -1};
    int Library2[] = {2, 3, 4, 5, 6, -1};
    int Library3[] = {0, 1, 2, 3, 4, 5, 6, 7, -1};
    int Library4[] = {0, 1, 2, -1};
    int Library5[] = {0, 6, 7, -1};
    int Library6[] = {0, 1, 2, 6, 7, -1};
    int Library7[] = {0, 1, 2, 3, 4, -1};
    int Library8[] = {0, 4, 5, 6, 7, -1};

    int * Library[] = {
        Library0, Library1, Library2,
        Library3, Library4, Library5,
        Library6, Library7, Library8,
    };

    // declare (and assign memory to) the array of valid search directions that will be returned
    //int *active_search;
    //active_search = (int *) malloc(SEARCH_DIRECTIONS * sizeof(int));


    // determine which is the correct array of search directions based on the current coordinate
    // top left corner
        int i = 0;
    if(row == 0 && col == 0){
        while(Library[0][i] != -1){
            active_search[i] = Library[0][i];
            i++;
        }
    }
    // top right corner
    else if(row == 0 && col == last_col){
        while(Library[1][i] != -1){
            active_search[i] = Library[1][i];
            i++;
        }
    }
    // non-edge columns of first row
    else if(row == 0 && (col != 0 || col != last_col)){
        while(Library[2][i] != -1){
            active_search[i] = Library[2][i];
            i++;
        }
    }
    // non-edge coordinates (no edge columns nor rows)
    else if(row != 0 && row != last_row && col != 0 && col != last_col){
        while(Library[3][i] != -1){
            active_search[i] = Library[3][i];
            i++;
        }
    }
    // bottom left corner
    else if(row == last_row && col == 0){
        while(Library[4][i] != -1){
            active_search[i] = Library[4][i];
            i++;
        }
    }
    // bottom right corner
    else if(row == last_row && col == last_col){
        while(Library[5][i] != -1){
            active_search[i] = Library[5][i];
            i++;
        }
    }
    // non-edge columns of last row
    else if(row == last_row && (col != 0 || col != last_col)){
        while(Library[6][i] != -1){
            active_search[i] = Library[6][i];
            i++;
        }
    }
    // non-edge rows of first column
    else if((row != 0 || row != last_row) && col == 0){
        while(Library[7][i] != -1){
            active_search[i] = Library[7][i];
            i++;
        }
    }
    // non-edge rows of last column
    else if((row != 0 || row != last_row) && col == last_col){
        while(Library[8][i] != -1){
            active_search[i] = Library[8][i];
            i++;
        }
    }
    active_search[i] = -1;
}
解决方案

Like others have said, you might want to post some of your code here, even if that's not the real point of your question. It might still be a good learning experience to have everyone here poke through your code and see if they can find what caused the segfault.

But yeah, the problem is that there are so many platform-dependent, as well as basically random, factors influencing a C program. Virtual memory means that sometimes, accessing unallocated memory will seem to work, because you hit an unused part of a page that's been allocated at some earlier point. Other times, it'll segfault because you hit a page that hasn't been allocated to your process at all. And that is really impossible to predict. It depends on where your memory was allocated, was it at the edge of a page, or in the middle? That's up to the OS and the memory manager, and which pages have been allocated so far, and...... You get the idea. Different compilers, different versions of the same compilers, different OS'es, different software, drivers or hardware installed on the system, anything can change whether or not you get a segfault when you access unallocated memory.

As for the TA's claim that cygwin is more "lax", that's rubbish, for one simple reason.Neither compiler caught the bug! If the "native" GCC compiler had truly been less lax, it would have given you an error at compile-time. Segfaults are not generated by the compiler. There's not much the compiler can do to ensure you get a segfault instead of a program that seemingly works.

这篇关于C程序用cygwin编译在Windows中工作,在Linux下分段故障。是cygwin GCC'坏'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 01:43