Программа на C, скомпилированная с помощью cygwin в Windows, работает, в Linux - ошибка сегментации. Cygwin GCC "плохой"?

В моем классе «Программирование 102» нас просят предоставить код C, который компилируется и запускается под Linux. У меня недостаточно свободного места на жестком диске для установки Linux вместе с Windows, поэтому я использую cygwin для компиляции своих программ.

Самая последняя программа, которую мне пришлось сдать, компилируется и отлично работает под cygwin. Он отлично компилируется под Linux, но на полпути выполнения вызывает ошибку сегментации. Я объяснил это аспиранту, который дает нам урок, и он сказал, что версия GCC для cygwin позволяет компилировать и выполнять более неаккуратный код.

Несколько ссылок, которые я нашел через Google, не были окончательными. В одном потоке, который я обнаружил, говорится, что причиной ошибки seg в Linux является утечка памяти. Почему это не повлияет на версию cygwin?

Я бы использовал университетские компьютеры, но я не могу использовать на них Subversion, что значительно затруднило бы мои усилия. (Я новичок в кодировании, и мне часто нужно иметь возможность вернуться к X ревизиям назад).

Действительно ли версия GCC от cygwin более «слабая» с кодом, который она компилирует? Если да, то есть ли какие-нибудь очевидные проблемы, на которые следует обратить внимание при кодировании? Есть ли альтернативы написанию кода, который будет работать под Linux?

Изменить

Спасибо за ответы. В своем исходном посте я не был достаточно явным: то, что в моем коде есть ошибка, было для меня в значительной степени само собой разумеющимся (в конце концов, я новичок в программировании и действительно зеленый, когда дело доходит до C). Мой TA подразумевал, что GCC cygwin - менее надежный компилятор, позволяющий запускать гораздо более неаккуратный код, чем тот, который можно найти в GNU / Linux. Я нашел это странным, и поэтому поискал в Интернете, но не смог найти никаких ссылок на этот факт.

Больше, чем обвинение компилятора в моем коде, мне было интересно, в чем причина того, что программа запускалась под Windows и вылетала из строя под Linux. Ответы о различных менеджерах памяти и структуре кучи / стека в Windows / Linux служат иллюстрацией в этом отношении.

Будет ли правильным вывод о том, что GCC cygwin так же «хорош», как и GNU / Linux, и что это базовые операционные системы / чистая удача, что моя программа с ошибками работает под одной, а не под другой?

Что касается публикации исходного кода, это домашнее задание, поэтому я бы предпочел сам найти проблему, если это вообще возможно :)

Изменить 2

Я принял ответ jalf, поскольку он говорит о том, что заставляет программу работать под Windows, а не под Linux, что я действительно хотел знать. Спасибо всем, кто внес свой вклад, все они были очень интересными и информативными ответами.

Когда я найду проблему и исправлю ее, я загружу zip-файл со всем исходным кодом этой нерабочей версии, на случай, если кому-то интересно посмотреть, что, черт возьми, я сделал :)

Изменить 3

Для тех, кто хочет увидеть код, я обнаружил, что проблема действительно связана с указателями. Я пытался вернуть указатель из функции. Указатель, который я пытался вернуть, объявлялся внутри функции и поэтому уничтожался после выполнения функции. Проблемный код закомментирован в строках 22-24.

Смело высмеивайте мой код.

/**
*  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;
}

person bob esponja    schedule 09.02.2009    source источник
comment
Можете выложить источник?   -  person geofftnz    schedule 10.02.2009
comment
Для тех, кто не может установить linux-проблема: получите live CD, загрузитесь с него, скомпилируйте его.   -  person Joachim Sauer    schedule 10.02.2009
comment
Кстати, здорово, что вы уже открыли для себя радости SVN. Я бы хотел, чтобы мне показали свет, когда я учился в колледже. ;)   -  person Nik Reiman    schedule 10.02.2009
comment
(Я новичок в кодировании, и мне часто нужно иметь возможность вернуться к X ревизиям назад) Я не новичок в кодировании, и мне часто нужно иметь возможность вернуться к X ревизиям назад. Не волнуйся, это хорошо. :)   -  person Robert P    schedule 10.02.2009
comment
@saua: использование Live CD будет похоже на использование компьютеров в университете: у меня нет доступной среды разработки (редактор настроен так, как мне нравится, подрывная деятельность и т. д.). @sqook: да, svn потрясающий. Я удивлен, что управление версиями даже не обсуждается в программировании 101.   -  person bob esponja    schedule 10.02.2009
comment
@Robert P: Я чувствую, что мне нужно использовать магию, которая возвращается гораздо чаще, чем опытные разработчики: P   -  person bob esponja    schedule 10.02.2009
comment
@bob: научитесь гибкости, чем раньше вы научитесь этому ;-) удачи   -  person Joachim Sauer    schedule 10.02.2009
comment
@bob: также: живой компакт-диск Ubuntu, например, позволяет вам создавать живую USB-флешку, которая позволяет вам делать настройки и даже устанавливать пакеты на флешку. Аккуратная особенность.   -  person Joachim Sauer    schedule 10.02.2009
comment
Что касается публикации исходного кода, это домашнее задание, поэтому я бы предпочел сам найти проблему, если это вообще возможно. Это отличное отношение. Было бы так, чтобы больше студентов чувствовали себя так же.   -  person Chris Upchurch    schedule 10.02.2009


Ответы (11)


Как уже говорили другие, вы можете разместить здесь часть своего кода, даже если это не суть вашего вопроса. По-прежнему может быть полезным для обучения, когда все здесь разбираются в вашем коде и смотрят, смогут ли они найти причину segfault.

Но да, проблема в том, что существует так много зависящих от платформы, а также в основном случайных факторов, влияющих на программу C. Виртуальная память означает, что иногда доступ к нераспределенной памяти будет работать, потому что вы попадаете в неиспользуемую часть страницы, которая была выделена ранее. В других случаях произойдет ошибка segfault, потому что вы попадете на страницу, которая вообще не была выделена для вашего процесса. И это действительно невозможно предсказать. Это зависит от того, где была выделена ваша память, на краю страницы или посередине? Это зависит от ОС и диспетчера памяти, а также от того, какие страницы были выделены на данный момент, и ... Вы уловили идею. Разные компиляторы, разные версии одних и тех же компиляторов, разные ОС, разное программное обеспечение, драйверы или оборудование, установленное в системе, все может измениться независимо от того, возникает ли у вас segfault при доступе к нераспределенной памяти.

Что касается утверждения ТА о том, что cygwin более «слабый», то это чушь по одной простой причине. Ни один из компиляторов не обнаружил ошибку! Если бы «родной» компилятор GCC действительно был менее слабым, он бы выдал вам ошибку во время компиляции. Компилятор не генерирует ошибки сегментации. Компилятор мало что может сделать, чтобы гарантировать, что вы получите segfault вместо программы, которая, казалось бы, работает.

person jalf    schedule 10.02.2009

Я не хочу показаться грубым, но, вероятно, плохой ваш код, а не компилятор. ;) Подобные проблемы на самом деле встречаются чаще, чем вы думаете, потому что разные ОС и компиляторы будут по-разному организовывать данные вашего приложения в стеке и куче. Первое может быть особенно проблематичным, особенно если вы в конечном итоге перезаписываете память в стеке или ссылаетесь на освобожденную память, которую система решила использовать для чего-то другого. В общем, иногда это может сойти с рук, но в других случаях ваше приложение задыхается и умирает. В любом случае, если это происходит с ошибкой, это потому, что вы пытались ссылаться на память, которая вам не разрешена, поэтому это скорее «счастливое совпадение», что она не вылетела под другой системой / компилятором.

Но на самом деле segfault - это segfault, поэтому вам следует вместо этого отлаживать свой код, ища повреждения памяти, вместо того, чтобы настраивать конфигурацию компилятора, чтобы выяснить, что идет не так.

Редактировать: Хорошо, теперь я понимаю, что вы имеете в виду ... Я думал, вы подошли к этой проблеме со словами «Х отстой, но Y отлично работает!» отношение, но похоже, что это у вашего ТА. ;)

В любом случае, вот еще несколько советов по устранению таких проблем:

  • Ищите арифметику указателя, ссылки / разыменование для возможного "doh!" ошибки. Особенно подозрительно любое место, где вы добавляете / вычитаете единицу (иначе говоря, ошибки столбов забора).
  • Закомментируйте вызовы malloc / free вокруг проблемной области и любых связанных областей, где используются эти указатели. Если код перестает давать сбой, значит, вы движетесь в правильном направлении.
  • Предполагая, что вы хотя бы определили общую область, в которой происходит сбой вашего кода, вставьте туда операторы раннего возврата и найдите точку, в которой ваш код не сбой. Это может помочь найти область где-нибудь между этой точкой и местом, где действительно происходит сбой кода. Помните, что подобный segfault не обязательно может произойти непосредственно в той строке кода, где находится ваша ошибка.
  • Use the memory debugging tools available on your system.
    • On Unix, check out this guide for debugging memory on unix, and the valgrind profiler (@Sol, thx for reminding me about this one)
    • В Visual Studio / Windows ваш старый добрый друг CrtCheckMemory () пригодится. Также ознакомьтесь с шаблонами отладки памяти CRT, поскольку они являются одними из более приятные возможности работы в VS. Часто достаточно просто оставить открытой вкладку памяти в VS, чтобы диагностировать подобные ошибки после того, как вы запомните различные шаблоны.
    • В Mac OSX вы можете установить точку останова на malloc_error_break (либо из gdb, либо из Xcode), что приведет к сбою отладчика всякий раз, когда malloc обнаруживает повреждение памяти. Я не уверен, доступно ли это в других версиях unix, но быстрый поиск в Google, похоже, показывает, что это только для Mac. Кроме того, для OSX, похоже, существует довольно "экспериментальная" версия valgrind.
person Nik Reiman    schedule 09.02.2009
comment
Но если он сможет настроить параметры компилятора так, чтобы его программа вылетала из строя на его компьютере так же, как в школе, тогда ему будет намного проще отлаживать. - person Rob Kennedy; 10.02.2009
comment
Возможно. По моему опыту, тем не менее, гораздо быстрее начать оглядываться назад с точки segfault, особенно на указатели и распределение памяти. Вовлечение нескольких систем будет сложнее, так как он сосредоточится на различиях между ними, а не на своей ошибке. - person Nik Reiman; 10.02.2009
comment
Совсем не грубо, в любом случае это то, что я себе представлял :) Я обязательно посмотрю на указатели, которые использую, спасибо за ответ. @Rob: это практически то решение, которое я бы искал. Хотя это не кажется возможным. - person bob esponja; 10.02.2009
comment
@sqook: это хороший момент, который вы подняли, возможно, решением было бы каким-то образом получить ящик Linux, в который я могу использовать SSH и скомпилировать / выполнить на нем, вместо того, чтобы пытаться использовать cygwin / Windows. - person bob esponja; 10.02.2009
comment
Что ж, я имел в виду, что вам не следует концентрироваться на различиях между cygwin / linux, но вы правы ... определенно будет легче исправить эту ошибку в системе, где вы можете воспроизвести ее. Отсутствие SVN может быть отстойным (кстати, разве вы не можете его там построить?), Но вы можете исправить эту ошибку и без него. Не сдавайся! - person Nik Reiman; 10.02.2009
comment
Если «строить там» означает на компьютерах uni, да, я могу и делаю. Проблема в том, что я затем пытаюсь отредактировать источник с помощью vim: «О, я уверен, что это просто небольшое изменение здесь, которое исправит его» x 100, и я получаю ужасно сломанный исходный файл без промежуточных ревизий для сравнения / вернуться к: P - person bob esponja; 10.02.2009
comment
Я имел в виду создание svn там. Например, ./configure --prefix = ~ / local, чтобы он находился в вашем домашнем каталоге. Затем вам просто нужно добавить $ HOME / local / bin в свой $ PATH, и вы дома бесплатно. - person Nik Reiman; 10.02.2009
comment
Проблема с подрывной деятельностью на самом деле заключается в том, что отдел «коммуникаций» заблокировал подрывные соединения на брандмауэре / прокси, а отдел «компьютерной лаборатории» ничего не может с этим поделать :( Я не хотел перегружать свой исходный пост ненужными Детали. - person bob esponja; 10.02.2009
comment
Также спасибо за дополнительную информацию, которую вы добавили, посмотрю завтра. Пора спать :) - person bob esponja; 10.02.2009
comment
Ба, как обидно ... действительно общение! Не использовать OT, но вы можете обслуживать свои репозитории через HTTP (visualsvn.com) или использовать бесплатную службу хостинга SVN (beanstalkapp.com). В любом случае, это, вероятно, хорошая тема для другого вопроса. ;) - person Nik Reiman; 10.02.2009
comment
Кто-нибудь знает об этом? valgrind для Linux - лучший инструмент для отладки кучи, который я когда-либо использовал. Это стандартный компонент в моем процессе разработки. (Я получаю свой последний код из SVN, строю на базе Linux, запускаю там valgrind и возвращаю его результат обратно на свою платформу разработки.) Это бесценно. - person Sol; 10.02.2009

Я не слышал ничего конкретного о странностях GCC под Cygwin, но в вашем случае, вероятно, было бы хорошей идеей использовать параметр командной строки -Wall для gcc, чтобы отображать все предупреждения, чтобы увидеть, найдет ли он что-нибудь, что может вызывать segfault в вашем коде.

person alxp    schedule 09.02.2009
comment
Спасибо за предложение. Я попробовал это в своем коде, и все, что он вызвал, было предупреждением о неиспользуемой переменной (не использовавшейся после попытки исправить эту проблему). - person bob esponja; 10.02.2009

У вас определенно есть ошибка где-то в вашем коде. Возможно, диспетчер памяти Windows более слабый, чем диспетчер памяти Linux. В Windows вы можете делать плохие вещи с памятью (например, перезаписывать границы массива, утечки памяти, двойное освобождение и т. Д.), Но это позволяет вам избежать неприятностей. Известную историю, связанную с этим, можно найти на странице http://www.joelonsoftware.com/article/APIWar.html (выполните поиск по запросу" SimCity "(довольно длинный ) статья).

person Adam Rosenfield    schedule 09.02.2009
comment
Спасибо за ответ и ссылку. Статья звонит в колокол, кажется, я прочитал ее несколько лет назад. Я обязательно изучу использование памяти. - person bob esponja; 10.02.2009

Почти наверняка это ошибка указателя или переполнение буфера, возможно, неинициализированная переменная.

Неинициализированный указатель обычно ни на что не указывает, но иногда он указывает на что-то; чтение из него или запись в него обычно приводит к сбою программы, но, опять же, МОЖЕТ нет.

Написание или чтение по свободной памяти - та же история; вам может сойти это с рук, но, может быть, и нет.

Эти ситуации зависят от того, как именно размещены стек, куча и что делает среда выполнения. Вполне возможно создать плохую программу, которая работает с одной комбинацией компилятор / среда выполнения, а не с другой, просто потому, что в одной из них она перезаписывает что-то, что не имеет значения (так много), или что неинициализированная переменная «случайно» содержит действительный значение для контекста, в котором оно используется.

person MarkR    schedule 09.02.2009
comment
Спасибо, это то объяснение, которое я искал, и оно подтверждает мои мысли. - person bob esponja; 10.02.2009
comment
Среда выполнения Windows C работает почти противоположно детектору границ памяти. Он довольно щедро распределяет страницы. Среда выполнения Linux C гораздо менее склонна к этому. Скорее хорошая функция на самом деле. - person Tim Williscroft; 10.02.2009

Версия gcc для Cygwin может иметь другие флаги по умолчанию и измененные настройки (например, wchar_t составляет 2 байта), но я сомневаюсь, что он более "слабый" с кодом и даже в этом случае - ваш код не должен аварийно завершить работу. Если это так, то, скорее всего, в вашем коде есть ошибка, которую нужно исправить. Например, ваш код может зависеть от конкретного размера wchar_t или может выполнять код, работа которого не гарантируется вообще, например запись в строковые литералы.

Если вы пишете чистый код, он работает и в Linux. В настоящее время я использую firefox и рабочий стол KDE, которые вместе состоят из миллионов строк C ++, и я не вижу сбоев этих приложений :)

Я рекомендую вам вставить свой код в свой вопрос, чтобы мы могли понять, что идет не так.

А пока вы можете запускать свою программу в gdb, отладчике для Linux. Вы также можете выполнить компиляцию со всеми включенными проверками брызговика и всеми предупреждениями. mudflaps проверяет ваш код во время выполнения на наличие различных нарушений:

[js@HOST2 cpp]$ cat mudf.cpp
int main(void)
{
  int a[10];
  a[10] = 3;  // oops, off by one.
  return 0;
}
[js@HOST2 cpp]$ g++ -fmudflap -fstack-protector-all -lmudflap -Wall mudf.cpp
[js@HOST2 cpp]$ MUDFLAP_OPTIONS=-help ./a.out
  ... showing many options ...
[js@HOST2 cpp]$ ./a.out 
*******                 
mudflap violation 1 (check/write): time=1234225118.232529 ptr=0xbf98af84 size=44
pc=0xb7f6026d location=`mudf.cpp:4:12 (main)'                                   
      /usr/lib/libmudflap.so.0(__mf_check+0x3d) [0xb7f6026d]                    
      ./a.out(main+0xb9) [0x804892d]                                            
      /usr/lib/libmudflap.so.0(__wrap_main+0x4f) [0xb7f5fa5f]                   
Nearby object 1: checked region begins 0B into and ends 4B after                
mudflap object 0x9731f20: name=`mudf.cpp:3:11 (main) int a [10]'                
bounds=[0xbf98af84,0xbf98afab] size=40 area=stack check=0r/3w liveness=3        
alloc time=1234225118.232519 pc=0xb7f5f9fd                                      
number of nearby objects: 1                                                     
*** stack smashing detected ***: ./a.out terminated                             
======= Backtrace: =========
....

Вы можете выполнить множество проверок брызговика, и вышеупомянутая процедура выполняется с использованием параметров по умолчанию. Еще один инструмент, который помогает от подобных ошибок, - это valgrind, который также может помочь вам найти утечки или устранить одну ошибку, как указано выше. Установка переменной среды «MALLOC_CHECK_» на 1 также будет печатать сообщения о нарушениях. См. Справочную страницу malloc, чтобы узнать о других возможных значениях этой переменной.

Чтобы проверить, где происходит сбой вашей программы, вы можете использовать gdb:

[js@HOST2 cpp]$ cat test.cpp
int main() {
    int *p = 0;
    *p = 0;
}
[js@HOST2 cpp]$ g++ -g3 -Wall test.cpp
[js@HOST2 cpp]$ gdb ./a.out
...
(gdb) r
Starting program: /home/js/cpp/a.out

Program received signal SIGSEGV, Segmentation fault.
0x080483df in main () at test.cpp:3
3           *p = 0;
(gdb) bt
#0  0x080483df in main () at test.cpp:3
(gdb)

Скомпилируйте свой код с помощью -g3, чтобы включить много отладочной информации, поэтому gdb может помочь вам найти точные строки, в которых ваша программа дает сбой. Все вышеперечисленные методы в равной степени применимы как для C, так и для C ++.

person Johannes Schaub - litb    schedule 09.02.2009
comment
Целью было отсутствие сбоев в коде :) Мне бы хотелось, чтобы моя программа в Windows работала так же, как и в Linux, но SSH в Linux для запуска кода, вероятно, поможет. PS Я вижу ваши миллионы строк неразрушающего C ++ и поднимаю вам свои 1000 строк C, которые с треском терпят крах :( - person bob esponja; 10.02.2009

Вероятно, проблема не в версии GCC. Скорее всего, это разница в библиотеке времени выполнения и ошибка в вашем коде, которая не проявляется при работе с версией среды выполнения для Windows. Возможно, вы захотите опубликовать код, который приводит к ошибке, и дополнительную справочную информацию, если хотите более конкретный ответ.

В общем, лучше всего разрабатывать в среде, которую вы собираетесь использовать для выполнения своего кода.

person Ori Pessach    schedule 09.02.2009

Ошибка сегментации означает, что вы пытались получить доступ к памяти, которую не могли, что обычно означает, что вы пытались разыменовать нулевой указатель или дважды удалили память или получили дикий указатель. Есть две причины, по которым вам могло показаться, что все в порядке на cygwin, а не на Linux: либо это была проблема с диспетчерами памяти, либо с одним из них вам повезло больше, чем с другим. Почти наверняка это ошибка вашего кода.

Чтобы исправить это, посмотрите на использование указателя. Рассмотрите возможность замены необработанных указателей интеллектуальными указателями. Подумайте о том, чтобы выполнить поиск для удаления и сразу после этого обнулить указатель (можно безопасно попытаться удалить нулевой указатель). Если у вас получится взломать Linux, попробуйте получить трассировку стека через gdb и посмотрите, есть ли что-то явно неправильное в строке, где это происходит. Изучите, как вы используете все указатели, которые не инициализированы. Если у вас есть доступ к инструменту отладки памяти, воспользуйтесь им.

person David Thornley    schedule 09.02.2009
comment
Посмотрим на использование указателя, спасибо. Получает ли трассировка стека расширенное использование gdb, или это будет объяснено в любом учебнике / ресурсах, которые я найду по отладке с помощью gdb? - person bob esponja; 10.02.2009
comment
Это довольно элементарно. Как только у вас появится gdb при сбое, введите bt для backtrace. Прошло некоторое время с тех пор, как я его использовал, но IIRC функция, которая потерпела крах, находится наверху, та, которая ее вызвала, просто внизу и т. Д. - person David Thornley; 10.02.2009

Делаете ли вы какие-либо предположения для конкретной платформы, например размер типов данных, выравнивание структуры данных в structs или порядок байтов?

person Zach Scrivena    schedule 09.02.2009
comment
или используете ли вы косую черту или обратную косую черту для путей к каталогам? - person rmeador; 10.02.2009
comment
Я не думаю, что программа, которую я пишу, достаточно сложна, чтобы столкнуться с проблемами порядка байтов (без побитовых операций). Я не использую много расширенных типов данных, большинство из них - это указатель на структуру, и я выделяю ему память с помощью malloc (sizeof (StructType)), что, я думаю, правильно. - person bob esponja; 10.02.2009
comment
@rmeador: Я использую косые черты для нескольких путей к каталогам, что является родным для Linux (верно?) и в Windows не вызывает у меня проблем. - person bob esponja; 10.02.2009
comment
@bob: со структурами вам также может потребоваться обратить внимание на проблемы с выравниванием байтов. (обновленный ответ, чтобы включить это) - person Zach Scrivena; 10.02.2009
comment
Указатель на структуру, которую я использую, имеет 3 члена, 2 члена, которые являются целыми числами, содержащими количество строк и столбцов, и 3-й член, который является двойным указателем на int (для имитации 2-го массива). Будет ли такая простая структура иметь проблемы с выравниванием байтов? - person bob esponja; 10.02.2009
comment
@bob: Зависит. Указатели имеют разные размеры на 32-битных и 64-битных машинах. Это также может повлиять на объединения внутри структур и наоборот. - person Zach Scrivena; 10.02.2009

Некоторые подсказки:

  1. Разместите свой код. Готов поспорить, вы получите хороший ввод, который сделает вас лучшим программистом.

  2. Включите предупреждения с помощью параметра -wall и исправьте все обнаруженные проблемы. Опять же, это может помочь вам стать лучшим программистом.

  3. Выполните код с помощью отладчика. Помимо того, что вы поймете, в чем проблема, это поможет вам стать лучшим программистом.

  4. Продолжайте использовать Subversion или другую систему управления исходным кодом.

  5. Никогда не обвиняйте компилятор (или ОС, или оборудование), пока не убедитесь, что вы точно выявили проблему. Даже в этом случае относитесь к собственному коду с подозрением.


Исходный код GCC в Linux идентичен GCC в Cygwin. Различия между платформами возникают из-за уровня эмуляции Cygwin POSIX и базового API Windows. Возможно, дополнительные слои более снисходительны, чем лежащее в основе оборудование, но на это нельзя рассчитывать.

Поскольку это домашнее задание, я бы сказал, что отправка кода - еще лучшая идея. Что может быть лучше, чем получение информации от профессиональных программистов? Однако я бы рекомендовал отметить любые предложения, которые вы реализуете, в ближайших комментариях.

person Jon Ericson    schedule 09.02.2009
comment
Спасибо за предложение re: posting code, я бы определенно был признателен за информацию о том, как улучшить мое кодирование, но я подожду, пока у меня не появится личный проект, код которого я смогу опубликовать; это домашнее задание :) Прочитаю, как работает отладка, пробовал в универе, но без особых результатов. - person bob esponja; 10.02.2009

Ошибка сегментации является результатом доступа к памяти по несуществующему (или ранее освобожденному) адресу. Что я нахожу очень интересным, так это то, что код НЕ выполнял segfault под cygwin. Это может означать, что ваша программа использовала дикий указатель на адресное пространство некоторых других процессов и действительно смогла его прочитать (вздох) или (что более вероятно) код, который фактически вызвал segfault, не был достигнут до тех пор, пока программа не была запущена под Linux .

Я рекомендую следующее:

  1. Вставьте свой код, так как это очень интересная проблема
  2. Отправьте копию разработчикам cygwin
  3. Купите дешевый Linux VPS, если вам потребуется создавать больше программ, работающих под Linux, это значительно упростит вашу жизнь.

После того, как вы начнете работать под Linux (то есть на своем VPS), попробуйте поработать со следующими программами:

  • GDB
  • Валгринд
  • Strace

Кроме того, вы можете попробовать библиотеки, такие как электрический забор, чтобы улавливать подобные вещи, когда они происходят во время работы вашей программы.

Наконец, убедитесь, что -Wall передан в gcc, вы хотите, чтобы он передавал предупреждения.

person Tim Post♦    schedule 10.02.2009