"Segmentation fault (core dumped)"
is the string that Linux prints when a program exits with a SIGSEGV
signal and you have core creation enabled. This means some program has crashed.
If you’re actually getting this error from running Python, this means the Python interpreter has crashed. There are only a few reasons this can happen:
-
You’re using a third-party extension module written in C, and that extension module has crashed.
-
You’re (directly or indirectly) using the built-in module
ctypes
, and calling external code that crashes. -
There’s something wrong with your Python installation.
-
You’ve discovered a bug in Python that you should report.
The first is by far the most common. If your q
is an instance of some object from some third-party extension module, you may want to look at the documentation.
Often, when C modules crash, it’s because you’re doing something which is invalid, or at least uncommon and untested. But whether it’s your «fault» in that sense or not — that doesn’t matter. The module should raise a Python exception that you can debug, instead of crashing. So, you should probably report a bug to whoever wrote the extension. But meanwhile, rather than waiting 6 months for the bug to be fixed and a new version to come out, you need to figure out what you did that triggered the crash, and whether there’s some different way to do what you want. Or switch to a different library.
On the other hand, since you’re reading and printing out data from somewhere else, it’s possible that your Python interpreter just read the line "Segmentation fault (core dumped)"
and faithfully printed what it read. In that case, some other program upstream presumably crashed. (It’s even possible that nobody crashed—if you fetched this page from the web and printed it out, you’d get that same line, right?) In your case, based on your comment, it’s probably the Java program that crashed.
If you’re not sure which case it is (and don’t want to learn how to do process management, core-file inspection, or C-level debugging today), there’s an easy way to test: After print line
add a line saying print "And I'm OK"
. If you see that after the Segmentation fault
line, then Python didn’t crash, someone else did. If you don’t see it, then it’s probably Python that’s crashed.
A segmentation fault (sometimes known as a segfault) happens when your program tries to access memory that it is not permitted to access.In other words, when your program attempts to access memory that exceeds the boundaries set by the operating system for your program.And it is a common circumstance that causes programs to crash; it is frequently related with a file called core.
Program memory is divided into different segments:
- a text segment for program instructions
- a data segment for variables and arrays defined at compile time
- a stack segment for temporary (or automatic) variables defined in subroutines and functions
- a heap segment for variables allocated during runtime by functions, such as malloc (in C) and allocate (in Fortran).
When a reference to a variable falls beyond the segment where that variable exists, or when a write is attempted to a place that is in a read-only segment, a segfault occurs. In reality, segfaults are nearly typically caused by attempting to read or write a non-existent array member, failing to correctly define a pointer before using it, or (in C applications) inadvertently using the value of a variable as an address (see the scan example below).
*Calling memset(), for example, would cause a program to segfault:
memset((char *)0x0, 1, 100);
*The three examples below show the most frequent sorts of array-related segfaults:
Case A
/* "Array out of bounds" error valid indices for array foo are 0, 1, ... 999 */
int foo[1000]; for (int i = 0; i <= 1000 ; i++) foo[i] = i;
Case B
/* Illegal memory access if value of n is not in the range 0, 1, ... 999 */
int n; int foo[1000]; for (int i = 0; i < n ; i++) foo[i] = i;
Case C
/* Illegal memory access because no memory is allocated for foo2 */
float *foo, *foo2; foo = (float*)malloc(1000); foo2[0] = 1.0;
- In case A, array foo is defined for index = 0, 1, 2, … 999. However, in the last iteration of the for loop, the program tries to access foo[1000]. This will result in a segfault if that memory location lies outside the memory segment where foo resides. Even if it doesn’t cause a segfault, it is still a bug.
- In case B, integer n could be any random value. As in case A, if it is not in the range 0, 1, … 999, it might cause a segfault. Whether it does or not, it is certainly a bug.
- In case C, allocation of memory for variable foo2 has been overlooked, so foo2 will point to a random location in memory. Accessing foo2[0] will likely result in a segfault.
*Another typical programming issue that causes segfaults is a failure to use pointers properly. The C function scanf(), for example, requires the address of a variable as its second parameter; hence, the following will very certainly cause the program to fail with a segfault:
int foo = 0; scanf("%d", foo);
/* Note missing & sign ; correct usage would have been &foo */
Although the variable foo may be created at memory position 1000, the preceding function call would attempt to read integer values into memory location 0 in accordance with the definition of foo.
A segfault occurs when a software attempts to operate on a memory region in an unauthorized manner (for example, attempts to write a read-only location would result in a segfault).When your application runs out of stack space, segfaults can occur. This might be due to your shell setting the stack size limit too low, rather than a fault in your software.
Dangling Pointers point to something that no longer exists.
A dangling pointer is an example of this.
char *ptr = NULL;
{
char c;
ptr = &c; //After the block is over, ptr will be a dangling pointer.
}
When the block concludes, the scope of variable c expires. Because it now points to something that doesn’t exist, the ‘ptr’ will become a dangling pointer.
But when you try to access memory that doesn’t belong to you or when you try to write to a read-only area, you get a segmentation fault.
char *str ="Testing Seg fault.";
*str= "I hate Seg fault :( ";
The’str’ will be made a constant by the compiler. You are altering the read-only part when you try to update the value, resulting in a segmentation fault.So there’s a clear distinction between a segmentation fault and dangling pointers.
A segmentation fault (sometimes known as a segfault) happens when your program tries to access memory that it is not permitted to access.In other words, when your program attempts to access memory that exceeds the boundaries set by the operating system for your program.And it is a common circumstance that causes programs to crash; it is frequently related with a file called core.
Program memory is divided into different segments:
- a text segment for program instructions
- a data segment for variables and arrays defined at compile time
- a stack segment for temporary (or automatic) variables defined in subroutines and functions
- a heap segment for variables allocated during runtime by functions, such as malloc (in C) and allocate (in Fortran).
When a reference to a variable falls beyond the segment where that variable exists, or when a write is attempted to a place that is in a read-only segment, a segfault occurs. In reality, segfaults are nearly typically caused by attempting to read or write a non-existent array member, failing to correctly define a pointer before using it, or (in C applications) inadvertently using the value of a variable as an address (see the scan example below).
*Calling memset(), for example, would cause a program to segfault:
memset((char *)0x0, 1, 100);
*The three examples below show the most frequent sorts of array-related segfaults:
Case A
/* "Array out of bounds" error valid indices for array foo are 0, 1, ... 999 */
int foo[1000]; for (int i = 0; i <= 1000 ; i++) foo[i] = i;
Case B
/* Illegal memory access if value of n is not in the range 0, 1, ... 999 */
int n; int foo[1000]; for (int i = 0; i < n ; i++) foo[i] = i;
Case C
/* Illegal memory access because no memory is allocated for foo2 */
float *foo, *foo2; foo = (float*)malloc(1000); foo2[0] = 1.0;
- In case A, array foo is defined for index = 0, 1, 2, … 999. However, in the last iteration of the for loop, the program tries to access foo[1000]. This will result in a segfault if that memory location lies outside the memory segment where foo resides. Even if it doesn’t cause a segfault, it is still a bug.
- In case B, integer n could be any random value. As in case A, if it is not in the range 0, 1, … 999, it might cause a segfault. Whether it does or not, it is certainly a bug.
- In case C, allocation of memory for variable foo2 has been overlooked, so foo2 will point to a random location in memory. Accessing foo2[0] will likely result in a segfault.
*Another typical programming issue that causes segfaults is a failure to use pointers properly. The C function scanf(), for example, requires the address of a variable as its second parameter; hence, the following will very certainly cause the program to fail with a segfault:
int foo = 0; scanf("%d", foo);
/* Note missing & sign ; correct usage would have been &foo */
Although the variable foo may be created at memory position 1000, the preceding function call would attempt to read integer values into memory location 0 in accordance with the definition of foo.
A segfault occurs when a software attempts to operate on a memory region in an unauthorized manner (for example, attempts to write a read-only location would result in a segfault).When your application runs out of stack space, segfaults can occur. This might be due to your shell setting the stack size limit too low, rather than a fault in your software.
Dangling Pointers point to something that no longer exists.
A dangling pointer is an example of this.
char *ptr = NULL;
{
char c;
ptr = &c; //After the block is over, ptr will be a dangling pointer.
}
When the block concludes, the scope of variable c expires. Because it now points to something that doesn’t exist, the ‘ptr’ will become a dangling pointer.
But when you try to access memory that doesn’t belong to you or when you try to write to a read-only area, you get a segmentation fault.
char *str ="Testing Seg fault.";
*str= "I hate Seg fault :( ";
The’str’ will be made a constant by the compiler. You are altering the read-only part when you try to update the value, resulting in a segmentation fault.So there’s a clear distinction between a segmentation fault and dangling pointers.
Не всегда программы в Linux запускаются как положено. Иногда, в силу разных причин программа вместо нормальной работы выдает ошибку. Но нам не нужна ошибка, нам нужна программа, вернее, та функция, которую она должна выполнять. Сегодня мы поговорим об одной из самых серьезных и непонятных ошибок. Это ошибка сегментации Ubuntu. Если такая ошибка происходит только один раз, то на нее можно не обращать внимания, но если это регулярное явление нужно что-то делать.
Конечно, случается эта проблема не только в Ubuntu, а во всех Linux дистрибутивах, поэтому наша инструкция будет актуальна для них тоже. Но сосредоточимся мы в основном на Ubuntu. Рассмотрим что такое ошибка сегментирования linux, почему она возникает, а также как с этим бороться и что делать.
Что такое ошибка сегментации?
Ошибка сегментации, Segmentation fault, или Segfault, или SIGSEGV в Ubuntu и других Unix подобных дистрибутивах, означает ошибку работы с памятью. Когда вы получаете эту ошибку, это значит, что срабатывает системный механизм защиты памяти, потому что программа попыталась получить доступ или записать данные в ту часть памяти, к которой у нее нет прав обращаться.
Чтобы понять почему так происходит, давайте рассмотрим как устроена работа с памятью в Linux, я попытаюсь все упростить, но приблизительно так оно и работает.
Допустим, в вашей системе есть 6 Гигабайт оперативной памяти, каждой программе нужно выделить определенную область, куда будет записана она сама, ее данные и новые данные, которые она будет создавать. Чтобы дать возможность каждой из запущенных программ использовать все шесть гигабайт памяти был придуман механизм виртуального адресного пространства. Создается виртуальное пространство очень большого размера, а из него уже выделяется по 6 Гб для каждой программы. Если интересно, это адресное пространство можно найти в файле /proc/kcore, только не вздумайте никуда его копировать.
Выделенное адресное пространство для программы называется сегментом. Как только программа попытается записать или прочитать данные не из своего сегмента, ядро отправит ей сигнал SIGSEGV и программа завершится с нашей ошибкой. Более того, каждый сегмент поделен на секции, в некоторые из них запись невозможна, другие нельзя выполнять, если программа и тут попытается сделать что-то запрещенное, мы опять получим ошибку сегментации Ubuntu.
Почему возникает ошибка сегментации?
И зачем бы это порядочной программе лезть, куда ей не положено? Да в принципе, незачем. Это происходит из-за ошибки при написании программ или несовместимых версиях библиотек и ПО. Часто эта ошибка встречается в программах на Си или C++. В этом языке программисты могут вручную работать с памятью, а язык со своей стороны не контролирует, чтобы они это делали правильно, поэтому одно неверное обращение к памяти может обрушить программу.
Почему может возникать эта ошибка при несовместимости библиотек? По той же причине — неверному обращению к памяти. Представим, что у нас есть библиотека linux (набор функций), в которой есть функция, которая выполняет определенную задачу. Для работы нашей функции нужны данные, поэтому при вызове ей нужно передать строку. Наша старая версия библиотеки ожидает, что длина строки будет до 256 символов. Но программа была обновлена формат записи поменялся, и теперь она передает библиотеке строку размером 512 символов. Если обновить программу, но оставить старую версию библиотеки, то при передаче такой строки 256 символов запишутся нормально в подготовленное место, а вот вторые 256 перезапишут данные программы, и возможно, попытаются выйти за пределы сегмента, тогда и будет ошибка сегментирования linux.
Что делать если возникла ошибка сегментирования?
Если вы думаете, что это ошибка в программе, то вам остается только отправить отчет об ошибке разработчикам. Но вы все-таки еще можете попытаться что-то сделать.
Например, если падает с ошибкой сегментации неизвестная программа, то мы можем решить что это вина разработчиков, но если с такой ошибкой падает chrome или firefox при запуске возникает вопрос, может мы делаем что-то не так? Ведь это уже хорошо протестированные программы.
Первое, что нужно сделать — это обновить систему до самой последней версии, возможно, был баг и его уже исправили, а может у вас установлены старые версии библиотек и обновление решит проблему. В Ubuntu это делается так:
sudo apt update
sudo apt full-upgrade
Если это не помогло, нужно обнулить настройки программы до значений по умолчанию, возможно, удалить кэш. Настройки программ в Linux обычно содержатся в домашней папке, скрытых подкаталогах с именем программы. Также, настройки и кэш могут содержаться в каталогах ~/.config и ~/.cache. Просто удалите папки программы и попробуйте снова ее запустить. Если и это не помогло, вы можете попробовать полностью удалить программу, а потом снова ее установить, возможно, какие-нибудь зависимости были повреждены:
sudo apt remove пакет_программы
sudo apt autoremove
sudo apt install пакет_программы
Если есть возможность, попробуйте установить программу из другого источника, например, не из PPA, а более старую версию, из официальных репозиториев.
Когда вы все это выполнили, скорее всего, проблема не в вашем дистрибутиве, а в самой программе. Нужно отправлять отчет разработчикам. В Ubuntu это можно сделать с помощью программы apport-bug. Обычно Ubuntu предлагает это сделать сразу, после того как программа завершилась с ошибкой сегментирования. Если же ошибка сегментирования Ubuntu встречается не в системной программе, то вам придется самим искать разработчиков и вручную описывать что произошло.
Чтобы помочь разработчикам решить проблему, недостаточно отправить им только сообщение что вы поймали Segmentation Fault, нужно подробно описать проблему, действия, которые вы выполняли перед этим, так чтобы разработчик мог их воспроизвести. Также, желательно прикрепить к отчету последние функции, которые вызывала программа (стек вызовов функций), это может очень сильно помочь разработчикам.
Рассмотрим, как его получить. Это не так уж сложно. Сначала запустите вашу программу, затем узнайте ее PID с помощью команды:
pgrep программа
Дальше запускаем отладчик gdb:
sudo gdb -q
Подключаемся к программе:
(gdb) attach ваш_pid
После подключения программа станет на паузу, продолжаем ее выполнение командой:
(gdb) continue
Затем вам осталось только вызвать ошибку:
И набрать команду, которая выведет стек последних вызовов:
(gdb) backtrace
Вывод этой команды и нужно отправлять разработчикам. Чтобы отключиться от программы и выйти наберите:
(gdb) detach
(gdb) quit
Дальше остается отправить отчет и ждать исправления ошибки. Если вы не уверены, что ошибка в программе, можете поспрашивать на форумах. Когда у вас есть стек вызовов, уже можно попытаться, если не понять в чем проблема, то попытаться узнать, не сталкивался ли с подобной проблемой еще кто-то.
Выводы
Теперь у вас есть приблизительный план действий, что нужно делать, когда появляется ошибка сегментирования сделан дамп памяти ubuntu. Если вы знаете другие способы решить эту проблему, напишите в комментариях!
Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .
29.12.2019C, C++
Что такое ошибка сегментации ?
— Это ошибка времени выполнения, вызванная нарушением доступа к памяти. Например: -Stackoverflow, читать нарушение и т. Д.
Мы часто сталкиваемся с этой проблемой при работе с указателями в c ++ / c.
В этом примере мы увидим, как найти ошибку сегментации в программе. Мы найдем, какие строки вызывают ошибку ошибки сегментации.
Примечание: — Я использовал дистрибутив Linux — Ubuntu для этой демонстрации.
Итак, рассмотрим следующий фрагмент кода C ++.
#include <iostream>
using
namespace
std;
int
main()
{
int
* p = NULL;
*p = 1;
cout << *p;
return
0;
}
Как найти эту ошибку с помощью GDB?
Допустим, ваше имя файла сохранено как Program1.cpp . Перейдите к нашему терминалу (будьте в каталоге, в котором доступен этот Program1.cpp)
Шаг 1: скомпилируйте его.
$ gcc -g Program1.cpp
(в моем случае).
Шаг 2: Запустите его.
$ ./a.out
(это объектный файл)
Если он показывает ошибку сегментации (ядро сброшено), выполните следующие действия.
Шаг 3: отладка
$ gdb ./a.out core
Ваш вывод будет выглядеть примерно так:
—————————-
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type show copying
and show warranty for details.
This GDB was configured as x86_64-linux-gnu.
Type show configuration for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type help.
Type apropos word to search for commands related to word...
Reading symbols from ./a.out...done.
/home/logarithm/Desktop/Test Case/Miccl/core: No such file or directory.
(gdb)
—————————-
Затем просто введите r и нажмите клавишу ввода.
Результат будет примерно таким, показывающим ошибочное утверждение.
—————————-
(gdb) r
Starting program: /home/logarithm/Desktop/Test Case/Miccl/a.out
Программа получила сигнал SIGSEGV, Ошибка сегментации.
0x00005555555547de в main () на Sege.cpp: 8
8 * р = 1;
(GDB)
—————————-
Теперь у вас есть строка, которая вызывает ошибку сегментации.
Выйдите из отладчика и исправьте программу.
Для выхода наберите quit и нажмите ввод.
—————————-
(gdb) quit
A debugging session is active.
Нижний 1 [процесс 3617] будет убит.
Выйти в любом случае? (у или н) у
—————————-
Итак, вау, вы разрешили ошибку сегментации пытки головы.
Рекомендуемые посты:
- Ошибка сегментации (SIGSEGV) и ошибка шины (SIGBUS)
- OpenCV: сегментация с использованием порога
- Базовый дамп (ошибка сегментации) в C / C ++
- Иначе без IF и L-Value Обязательная ошибка в C
- Обработка ошибок в программах на Си
- эрф | Функции ошибок, использующие cmath в C ++
- Программные сигналы об ошибках
- std :: find в C ++
- функция поиска карты () в C ++ STL
- установить функцию find () в C ++ STL
- мультикарта find () в C ++ STL
- unordered_map найти в C ++ STL
- поиск строки в C ++
- Найдите N-й член ряда 14, 28, 20, 40, …..
- Как найти сумму элементов вектора с использованием STL в C ++?
Как найти ошибку сегментации в C & C ++? (С использованием GDB)
0.00 (0%) 0 votes
Вопрос:
Я получил ошибку разбивки сегментации (core dumped) и попробовал отладку с помощью gdb. Я узнал, где произошла ошибка:
Program received signal SIGSEGV, Segmentation fault.
0x08048edb in state_update2 () at xxx.cpp:333
333 if (rob.head->is_complete == 1 && rob.head->ready_to_retire == 1 )
Несколько строк кода:
if(rob.head->is_complete == 1 && rob.head->ready_to_retire == 1) {
reorder_buffer_node *temp = new reorder_buffer_node[sizeof(struct reorder_buffer_node)];
temp = rob.head;
for(uint64_t i=0; i<f_; i++) {
if(temp->is_complete == 1 && temp->ready_to_retire == 1) {
rob.pop();
retired_inst++;
temp = temp->next;
}
else break;
}
}
ROB представляет собой циклическую очередь, а head – указатель на структуру, которая имеет вид:
struct reorder_buffer_node {
int is_complete;
uint64_t instr_num;
uint64_t dest_reg;
uint64_t index;
reorder_buffer_node *next;
int ready_to_retire;
};
Не обращаюсь к членам структуры правильно? Пожалуйста, дайте мне знать!
Ответ №1
reorder_buffer_node *temp = new reorder_buffer_node[sizeof(struct reorder_buffer_node)];
//Вы пытаетесь создать массив reorder_buffer_node и имя как temp??
temp = rob.head;
//С вышеуказанным комментарием эта строка не будет
temp = temp->next;
//Вы не написали конструктор для структуры, поэтому с конструктором по умолчанию, temp будет назначен мусору или NULL. Когда вы выполните вышеуказанный шаг, это может привести к ошибке сегментации или сбою. Настолько лучше написать конструктор.
Если последующие шаги по его соблюдению будут выполняться правильно.
Ответ №2
У меня недостаточно контекста, чтобы сказать наверняка, но я бы начал с этих двух строк:
reorder_buffer_node *temp = new reorder_buffer_node[sizeof(struct reorder_buffer_node)];
temp = rob.head;
Который уничтожает ценность new
способом, подобным:
int temp = 15;
temp = 5;
Ответ №3
Если я понимаю, что вы правильно потерпели крах, то происходит if()? Итак, как вы упомянули, что голова указатель, может быть, она не выделена? Если в приведенном ниже коде приведена ошибка сегментации:
if(rob.head->is_complete == 1 && rob.head->ready_to_retire == 1)
Чтобы проверить это, вы можете просто указатель распечатки или добавить check для NULL для этого указателя.
Хотя комментарии Weather Vane и yano верны, эти ошибки вряд ли вызовут ошибки сегментации:
-
Вы все еще можете получить доступ к памяти локальных переменных в C после выхода из функции, вы просто не можете гарантировать, что данные будут действительными.
Локальные переменные выделяются в стеке, поэтому сам адрес останется действительным для процесса.
-
Строка нулевой длины «» по-прежнему занимает массив длиной 1 в C из-за завершающего символа 0.
Кроме того, превышение границ локального массива в C не обязательно вызовет ошибку seg, в зависимости от структуры памяти функции.
Что гарантированно устранит ошибку сегментации, так это эта строка:
int password_comparison = strcmp(«090097099104082111104105116104083097109050048049056101104099115067104117114099104079102069109097099115095095», password_input);
В вашем коде password_input имеет тип char и, предположительно, содержит значение, которое гарантированно находится в диапазоне от -127 до 127.
Но strcmp будет рассматривать его как указатель — адрес в памяти от 0 до 255.
Адреса в этом диапазоне недействительны, поэтому, когда strcmp пытается его прочитать, это всегда вызывает ошибку сегментации.
C язык, неисправность сегментации (ядро сбрасывается)Быть неправым
Причиной:Ошибка абзаца заключается в том, что память доступа находится вне пространства памяти для программы к этой программе. Как правило, свободно использовать дикие указатели или массивы, массивные кресты.
Метод позиционирования:
1Используя отладку оператора вывода, обычно используемые в отладке одного документа, где указатель используется для использования неправильного места для выходных операторов, сprintf(“%dn”, __LINE__); Последнее количество печатных строк — это количество возникающих рядов.
(Возьмите это в качестве примера)
(Последняя строка печати — это 7-я строка, доказательство Программа неверна в 8-й строке)
2,использоватьgdbВвод в эксплуатацию, обычно используемый в мульти-документе отладки,gcc x.c -o x
gdb x
run
Затем постоянно входитеrun+Введите, остановитесь при работе в случае ошибки абзацаrunИ расположена в строке документа, изменение является передней линейкой ошибки абзаца.
(Последняя строка печати — это 7-я строка, доказательство Программа неверна в 8-й строке)
Метод отладки решения:Адрес указателя, используемого в переднем ряду ошибки произошел, как показано на рисунке, адрес указателяnilПредставляя дикий указатель указателя, использование дикого указателя определенно является абзацем!
Это мое понимание абзацев, если есть лучший путь или неправильное место, пожалуйста, отдайте это.
Я новичок в Python и получаю странную ошибку:
Segmentation fault (core dumped)
Когда я выполняю следующий код:
class Workspace(QMainWindow, Ui_MainWindow):
""" This class is for managing the whole GUI `Workspace'.
Currently a Workspace is similar to a MainWindow
"""
def __init__(self):
#p= subprocess.Popen(["java -Xmx256m -jar bin/HelloWorld.jar"],cwd=r'/home/karen/sphinx4-1.0beta5-src/sphinx4-1.0beta5/', shell=True, stdout=subprocess.PIPE, bufsize= 4024)
try:
from Queue import Queue, Empty
except ImportError:
while True:
#from queue import Queue, Empty # python 3.x
print "error"
ON_POSIX = 'posix' in sys.builtin_module_names
def enqueue_output(out, queue):
for line in iter(out.readline, b''):
queue.put(line)
out.close()
p= Popen(["java -Xmx256m -jar bin/HelloWorld.jar"],cwd=r'/home/karen/sphinx4-1.0beta5-src/sphinx4-1.0beta5/',stdout=PIPE, shell=True, bufsize= 4024)
q = Queue()
t = threading.Thread(target=enqueue_output, args=(p.stdout, q))
#t = Thread(target=enqueue_output, args=(p.stdout, q))
t.daemon = True # thread dies with the program
t.start()
# ... do other things here
def myfunc(q):
while True:
try: line = q.get_nowait()
# or q.get(timeout=.1)
except Empty:
print('Vacio')
else: # got line
# ... do something with line
print line
thread = threading.Thread(target=myfunc, args=(q,))
thread.start()
Эта часть кода читает из стандартного вывода программы. Когда я выполняю myfunc
из потока, он работает! Но когда я выполню это в потоке fais … Любое предложение?
6 ответов
Лучший ответ
"Segmentation fault (core dumped)"
— это строка, которую печатает Linux, когда программа выходит с сигналом SIGSEGV
и у вас включено создание ядра. Это означает, что какая-то программа потерпела крах.
Если вы на самом деле получаете эту ошибку при запуске Python, это означает, что интерпретатор Python потерпел крах. Это может произойти только по нескольким причинам:
-
Вы используете сторонний модуль расширения, написанный на C, и этот модуль расширения вышел из строя.
-
Вы (прямо или косвенно) используете встроенный модуль
ctypes
и вызываете внешний аварийный код. -
Что-то не так с вашей установкой Python.
-
Вы обнаружили ошибку в Python, о которой вы должны сообщить.
Первый, безусловно, самый распространенный. Если ваш q
является экземпляром какого-либо объекта из какого-либо стороннего модуля расширения, вы можете посмотреть документацию.
Часто, когда происходит сбой модулей C, это происходит потому, что вы делаете что-то недопустимое или, по крайней мере, необычное и непроверенное. Но неважно, твоя ли это «вина» в этом смысле или нет. Модуль должен вызвать исключение Python, которое вы можете отлаживать вместо сбоя. Таким образом, вы, вероятно, должны сообщить об ошибке любому, кто написал расширение. Но в то же время, вместо того, чтобы ждать 6 месяцев, чтобы ошибка была исправлена и появилась новая версия, вам нужно выяснить, что вы сделали, что вызвало сбой, и есть ли какой-то другой способ сделать то, что вы хотите. Или переключитесь на другую библиотеку.
С другой стороны, поскольку вы читаете и распечатываете данные откуда-то еще, возможно, ваш интерпретатор Python просто прочитал строку "Segmentation fault (core dumped)"
и точно напечатал прочитанное. В этом случае какая-то другая программа в апстриме предположительно потерпела крах. (Возможно даже, что никто не рухнул — если вы взяли эту страницу из Интернета и распечатали ее, вы бы получили ту же строку, верно?) В вашем случае, основываясь на вашем комментарии, вероятно, произошла ошибка программы Java.
Если вы не уверены, в каком случае это происходит (и не хотите изучать, как выполнять управление процессами, проверку файла ядра или отладку на уровне C сегодня), есть простой способ проверить: после print line
добавьте строку со словами print "And I'm OK"
. Если вы видите это после строки Segmentation fault
, то Python не падает, кто-то другой сделал. Если вы этого не видите, то, вероятно, сбился Python.
80
Alexander Stohr
9 Сен 2019 в 16:45
Есть еще одна причина такой неудачи, о которой я узнал, когда моя вышла из строя
- Возможно, вы работаете с большим количеством данных, и ваша память заполнена
Это может не применяться в этом случае, но также выдает ту же ошибку, и поскольку этот вопрос стоит выше этой ошибки, я добавил этот ответ здесь.
57
Cybersupernova
10 Янв 2020 в 10:55
Стоит попробовать обработчик ошибок, чтобы определить строку или библиотеку, которая вызывает проблему, как указано здесь https://stackoverflow.com/a/58825725 / 2160809 и в комментариях Каруханги
faulthandler.enable()
// bad code goes here
Или
$ python3 -q -X faulthandler
>>> /// bad cod goes here
0
cookiemonster
26 Фев 2020 в 12:59
В моем случае: я забыл активировать virtualenv
Я установил «пример установки pip» в неправильном virtualenv
4
HoangYell
2 Май 2019 в 14:02
В моем случае я импортирую модуль pyxlsb перед модулем, который работает с db Mysql. После того, как я сначала поставил модуль Mysql (верхний в коде), он стал работать как часы. Думаю, была проблема с пространством имен.
1
Александр Тарасов
12 Фев 2019 в 19:50
TL: DR: используйте gcc -m32
.
.code32
делает not изменение формата выходного файла, и именно это определяет режим, в котором будет работать ваша программа. вам не нужно запускать 32-битный код в режиме 64 бит. .code32
предназначен для сборки «чужого» машинного кода, который может потребоваться в качестве данных, или для экспорта в сегменте общей памяти. Если это не то, что вы делаете, избегайте его, чтобы получить ошибки времени сборки, когда вы создаете .S
в неправильном режиме, если у него есть, например, команды push
или pop
.
Предложение: используйте расширение .S
для рукописного ассемблера. (gcc foo.S
будет запускать его через препроцессор C до as
, поэтому вы можете #include
заголовок с номерами системного вызова, например). Кроме того, он отличает его от выхода компилятора .s
(от gcc foo.c -O3 -S
).
Чтобы создать 32-битные двоичные файлы, используйте одну из этих команд
gcc -g foo.S -o foo -m32 -nostdlib -static # static binary with absolutely no libraries or startup code
# -nostdlib by itself makes static executables on Linux, but not OS X.
gcc -g foo.S -o foo -m32 # dynamic binary including the startup boilerplate code. Use with code that defines a main() but not a _start
Документация для nostdlib
, -nostartfiles
и -static
.
Использование функций libc из _start
(см. конец этого ответа для примера)
Некоторые функции, такие как функции malloc(3)
или stdio, включая printf(3)
, зависят от инициализации некоторых глобальных данных (например, FILE *stdout
и объекта, на который он фактически указывает).
gcc -nostartfiles
оставляет из кода шаблона CRT _start
, но все же ссылки libc
(динамически, по умолчанию). В Linux общие библиотеки могут иметь разделы инициализатора, которые запускаются динамическим компоновщиком, когда он загружает их, прежде чем переходить к вашей точке входа _start
. Таким образом, gcc -nostartfiles hello.S
все еще позволяет вам называть printf
. Для динамического исполняемого файла ядро запускает на нем /lib/ld-linux.so.2
вместо его непосредственного использования (используйте readelf -a
, чтобы увидеть строку «ELF интерпретатор» в вашем двоичном файле). Когда ваш _start
в конечном итоге будет запущен, не все регистры будут обнулены, потому что динамический компоновщик выполнил код в вашем процессе.
Однако gcc -nostartfiles -static hello.S
свяжется, но сбой во время выполнения, если вы вызываете printf
или что-то, не вызывая внутренние функции init glibc. (см. комментарий Майкла Пётча).
Конечно, вы можете поместить любую комбинацию файлов .c
, .S
и .o
в одну и ту же командную строку, чтобы связать их все в один исполняемый файл , Если у вас есть C, не забудьте -Og -Wall -Wextra
: вы не хотите отлаживать ваш asm, когда проблема была чем-то простым в C, который вызывает это, о котором мог бы предупредить компилятор.
Используйте -v
, чтобы gcc показывал вам команды, которые он запускает для сборки и соединения. Для этого «вручную»:
as foo.S -o foo.o -g --32 && # skips the preprocessor
ld -o foo foo.o -m elf_i386
file foo
foo: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped
gcc -nostdlib -m32
легче запомнить и ввести, чем два разных варианта для as и ld (--32
и -m elf_i386
). Кроме того, он работает на всех платформах, включая те, где исполняемый формат не является ELF. (Но примеры Linux не будут работать в OS X, потому что номера системных вызовов различны или в Windows, потому что в нем даже не используется int 0x80
ABI.)
NASM / YASM
gcc не может обрабатывать синтаксис NASM. (-masm=intel
больше похож на MASM, чем на синтаксис NASM, где вам нужно offset symbol
, чтобы получить адрес как немедленный). И, конечно, директивы различны (например, .globl
vs global
).
Вы можете построить с помощью nasm
или yasm
, затем свяжите .o
с gcc
, как указано выше, или ld
напрямую.
Я использую сценарий оболочки, чтобы избежать повторного ввода одного и того же имени файла с тремя разными расширениями. (nasm и yasm по умолчанию file.asm
-> file.o
, в отличие от вывода GNU as по умолчанию a.out
). Используйте это с помощью -m32
, чтобы собрать и связать 32-разрядные исполняемые файлы ELF. Не все ОС используют ELF, поэтому этот скрипт менее переносим, чем использование gcc -nostdlib -m32
для ссылки будет ..
#!/bin/sh
# usage: asm-link [-q] [-m32] foo.asm [assembler options ...]
# Just use a Makefile for anything non-trivial. This script is intentionally minimal and doesn't handle multiple source files
verbose=1 # defaults
fmt=-felf64
#ldopt=-melf_i386
while getopts 'm:vq' opt; do
case "$opt" in
m) if [ "m$OPTARG" = "m32" ]; then
fmt=-felf32
ldopt=-melf_i386
fi
if [ "m$OPTARG" = "mx32" ]; then
fmt=-felfx32
ldopt=-melf32_x86_64
fi
# default is -m64
;;
q) verbose=0 ;;
v) verbose=1 ;;
esac
done
shift "$((OPTIND-1))" # Shift off the options and optional --
src=$1
base=${src%.*}
shift
[ "$verbose" = 1 ] && set -x # print commands as they're run, like make
#yasm "$fmt" -Worphan-labels -gdwarf2 "$src" "$@" &&
nasm "$fmt" -Worphan-labels -g -Fdwarf "$src" "$@" &&
ld $ldopt -o "$base" "$base.o"
# yasm -gdwarf2 includes even .local labels so they show up in objdump output
# nasm defaults to that behaviour of including even .local labels
# nasm defaults to STABS debugging format, but -g is not the default
Я предпочитаю yasm по нескольким причинам, в том числе по умолчанию для создания long- nop
s вместо заполнения со многими однобайтными nop
s. Это приводит к беспорядочному выводу разборки, а также к замедлению, если nops когда-либо выполняются. (В NASM вам необходимо использовать макрос smartalign
.)
Пример: программа, использующая функции libc из _start
# hello32.S
#include <asm/unistd_32.h> // syscall numbers. only #defines, no C declarations left after CPP to cause asm syntax errors
.text
#.global main # uncomment these to let this code work as _start, or as main called by glibc _start
#main:
#.weak _start
.global _start
_start:
mov $__NR_gettimeofday, %eax # make a syscall that we can see in strace output so we know when we get here
int $0x80
push %esp
push $print_fmt
call printf
#xor %ebx,%ebx # _exit(0)
#mov $__NR_exit_group, %eax # same as glibc's _exit(2) wrapper
#int $0x80 # won't flush the stdio buffer
movl $0, (%esp) # reuse the stack slots we set up for printf, instead of popping
call exit # exit(3) does an fflush and other cleanup
#add $8, %esp # pop the space reserved by the two pushes
#ret # only works in main, not _start
.section .rodata
print_fmt: .asciz "Hello, World!n%%esp at startup = %#lxn"
$ gcc -m32 -nostdlib hello32.S
/tmp/ccHNGx24.o: In function `_start':
(.text+0x7): undefined reference to `printf'
...
$ gcc -m32 hello32.S
/tmp/ccQ4SOR8.o: In function `_start':
(.text+0x0): multiple definition of `_start'
...
Не работает во время выполнения, потому что ничего не вызывает функции glibc init. (__libc_init_first
, __dl_tls_setup
и __libc_csu_init
в этом порядке, в соответствии с комментарием Майкла Пётча. Существуют и другие реализации libc
, в том числе MUSL , который предназначен для статической компоновки и работает без вызовов инициализации .)
$ gcc -m32 -nostartfiles -static hello32.S # fails at run-time
$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, BuildID[sha1]=ef4b74b1c29618d89ad60dbc6f9517d7cdec3236, not stripped
$ strace -s128 ./a.out
execve("./a.out", ["./a.out"], [/* 70 vars */]) = 0
[ Process PID=29681 runs in 32 bit mode. ]
gettimeofday(NULL, NULL) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)
Вы также можете gdb ./a.out
и запустить b _start
, layout reg
, run
и посмотреть, что произойдет.
$ gcc -m32 -nostartfiles hello32.S # Correct command line
$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=7b0a731f9b24a77bee41c13ec562ba2a459d91c7, not stripped
$ ./a.out
Hello, World!
%esp at startup = 0xffdf7460
$ ltrace -s128 ./a.out > /dev/null
printf("Hello, World!n%%esp at startup = %#lxn", 0xff937510) = 43 # note the different address: Address-space layout randomization at work
exit(0 <no return ...>
+++ exited (status 0) +++
$ strace -s128 ./a.out > /dev/null # redirect stdout so we don't see a mix of normal output and trace output
execve("./a.out", ["./a.out"], [/* 70 vars */]) = 0
[ Process PID=29729 runs in 32 bit mode. ]
brk(0) = 0x834e000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
.... more syscalls from dynamic linker code
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
mmap2(NULL, 1814236, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xfffffffff7556000 # map the executable text section of the library
... more stuff
# end of dynamic linker's code, finally jumps to our _start
gettimeofday({1461874556, 431117}, NULL) = 0
fstat64(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0 # stdio is figuring out whether stdout is a terminal or not
ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0xff938870) = -1 ENOTTY (Inappropriate ioctl for device)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffffffff7743000 # 4k buffer for stdout
write(1, "Hello, World!n%esp at startup = 0xff938fb0n", 43) = 43
exit_group(0) = ?
+++ exited with 0 +++
Если бы мы использовали _exit(0)
или сделали систему sys_exit
называть себя int 0x80
, , то write(2)
не было бы . Если stdout перенаправлен на не-tty, по умолчанию он заполняется с полным буфером (не с буферизацией строки), поэтому write(2)
запускается только fflush(3)
как часть exit(3)
. Без перенаправления вызов printf(3)
со строкой, содержащей символы новой строки, будет немедленно скрыт.
Поведение в зависимости от того, является ли stdout терминалом, может быть желательно, но только если вы делаете это специально, а не по ошибке.
Не всегда программы в Linux запускаются как положено. Иногда, в силу разных причин программа вместо нормальной работы выдает ошибку. Но нам не нужна ошибка, нам нужна программа, вернее, та функция, которую она должна выполнять. Сегодня мы поговорим об одной из самых серьезных и непонятных ошибок. Это ошибка сегментации Ubuntu. Если такая ошибка происходит только один раз, то на нее можно не обращать внимания, но если это регулярное явление нужно что-то делать.
Конечно, случается эта проблема не только в Ubuntu, а во всех Linux дистрибутивах, поэтому наша инструкция будет актуальна для них тоже. Но сосредоточимся мы в основном на Ubuntu. Рассмотрим что такое ошибка сегментирования linux, почему она возникает, а также как с этим бороться и что делать.
Что такое ошибка сегментации?
Ошибка сегментации, Segmentation fault, или Segfault, или SIGSEGV в Ubuntu и других Unix подобных дистрибутивах, означает ошибку работы с памятью. Когда вы получаете эту ошибку, это значит, что срабатывает системный механизм защиты памяти, потому что программа попыталась получить доступ или записать данные в ту часть памяти, к которой у нее нет прав обращаться.
Чтобы понять почему так происходит, давайте рассмотрим как устроена работа с памятью в Linux, я попытаюсь все упростить, но приблизительно так оно и работает.
Допустим, в вашей системе есть 6 Гигабайт оперативной памяти, каждой программе нужно выделить определенную область, куда будет записана она сама, ее данные и новые данные, которые она будет создавать. Чтобы дать возможность каждой из запущенных программ использовать все шесть гигабайт памяти был придуман механизм виртуального адресного пространства. Создается виртуальное пространство очень большого размера, а из него уже выделяется по 6 Гб для каждой программы. Если интересно, это адресное пространство можно найти в файле /proc/kcore, только не вздумайте никуда его копировать.
Выделенное адресное пространство для программы называется сегментом. Как только программа попытается записать или прочитать данные не из своего сегмента, ядро отправит ей сигнал SIGSEGV и программа завершится с нашей ошибкой. Более того, каждый сегмент поделен на секции, в некоторые из них запись невозможна, другие нельзя выполнять, если программа и тут попытается сделать что-то запрещенное, мы опять получим ошибку сегментации Ubuntu.
Почему возникает ошибка сегментации?
И зачем бы это порядочной программе лезть, куда ей не положено? Да в принципе, незачем. Это происходит из-за ошибки при написании программ или несовместимых версиях библиотек и ПО. Часто эта ошибка встречается в программах на Си или C++. В этом языке программисты могут вручную работать с памятью, а язык со своей стороны не контролирует, чтобы они это делали правильно, поэтому одно неверное обращение к памяти может обрушить программу.
Почему может возникать эта ошибка при несовместимости библиотек? По той же причине — неверному обращению к памяти. Представим, что у нас есть библиотека linux (набор функций), в которой есть функция, которая выполняет определенную задачу. Для работы нашей функции нужны данные, поэтому при вызове ей нужно передать строку. Наша старая версия библиотеки ожидает, что длина строки будет до 256 символов. Но программа была обновлена формат записи поменялся, и теперь она передает библиотеке строку размером 512 символов. Если обновить программу, но оставить старую версию библиотеки, то при передаче такой строки 256 символов запишутся нормально в подготовленное место, а вот вторые 256 перезапишут данные программы, и возможно, попытаются выйти за пределы сегмента, тогда и будет ошибка сегментирования linux.
Что делать если возникла ошибка сегментирования?
Если вы думаете, что это ошибка в программе, то вам остается только отправить отчет об ошибке разработчикам. Но вы все-таки еще можете попытаться что-то сделать.
Например, если падает с ошибкой сегментации неизвестная программа, то мы можем решить что это вина разработчиков, но если с такой ошибкой падает chrome или firefox при запуске возникает вопрос, может мы делаем что-то не так? Ведь это уже хорошо протестированные программы.
Первое, что нужно сделать — это обновить систему до самой последней версии, возможно, был баг и его уже исправили, а может у вас установлены старые версии библиотек и обновление решит проблему. В Ubuntu это делается так:
sudo apt update
sudo apt full-upgrade
Если это не помогло, нужно обнулить настройки программы до значений по умолчанию, возможно, удалить кэш. Настройки программ в Linux обычно содержатся в домашней папке, скрытых подкаталогах с именем программы. Также, настройки и кэш могут содержаться в каталогах ~/.config и ~/.cache. Просто удалите папки программы и попробуйте снова ее запустить. Если и это не помогло, вы можете попробовать полностью удалить программу, а потом снова ее установить, возможно, какие-нибудь зависимости были повреждены:
sudo apt remove пакет_программы
sudo apt autoremove
sudo apt install пакет_программы
Если есть возможность, попробуйте установить программу из другого источника, например, не из PPA, а более старую версию, из официальных репозиториев.
Когда вы все это выполнили, скорее всего, проблема не в вашем дистрибутиве, а в самой программе. Нужно отправлять отчет разработчикам. В Ubuntu это можно сделать с помощью программы apport-bug. Обычно Ubuntu предлагает это сделать сразу, после того как программа завершилась с ошибкой сегментирования. Если же ошибка сегментирования Ubuntu встречается не в системной программе, то вам придется самим искать разработчиков и вручную описывать что произошло.
Чтобы помочь разработчикам решить проблему, недостаточно отправить им только сообщение что вы поймали Segmentation Fault, нужно подробно описать проблему, действия, которые вы выполняли перед этим, так чтобы разработчик мог их воспроизвести. Также, желательно прикрепить к отчету последние функции, которые вызывала программа (стек вызовов функций), это может очень сильно помочь разработчикам.
Рассмотрим, как его получить. Это не так уж сложно. Сначала запустите вашу программу, затем узнайте ее PID с помощью команды:
pgrep программа
Дальше запускаем отладчик gdb:
sudo gdb -q
Подключаемся к программе:
(gdb) attach ваш_pid
После подключения программа станет на паузу, продолжаем ее выполнение командой:
(gdb) continue
Затем вам осталось только вызвать ошибку:
И набрать команду, которая выведет стек последних вызовов:
(gdb) backtrace
Вывод этой команды и нужно отправлять разработчикам. Чтобы отключиться от программы и выйти наберите:
(gdb) detach
(gdb) quit
Дальше остается отправить отчет и ждать исправления ошибки. Если вы не уверены, что ошибка в программе, можете поспрашивать на форумах. Когда у вас есть стек вызовов, уже можно попытаться, если не понять в чем проблема, то попытаться узнать, не сталкивался ли с подобной проблемой еще кто-то.
Выводы
Теперь у вас есть приблизительный план действий, что нужно делать, когда появляется ошибка сегментирования сделан дамп памяти ubuntu. Если вы знаете другие способы решить эту проблему, напишите в комментариях!
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.
Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .
После исследования я верю, что понимаю, что "Segmentation fault"
ошибка Тем не менее, даже после комментирования кода строка за строкой, я не могу найти, где происходит ошибка, чтобы исправить ее. Есть ли что-то, что я пропускаю, что вызывает эту ошибку? Ниже показано, что появляется, когда я запускаю код:
Готовы играть (да / нет)? Y
3C AH 4C 3H 4H 2H 5H 2C 5C AC
Вот ваши карты: 3C AH 4C 3H 4H
Ошибка сегментации (ядро сброшено)
Ниже приведен код, на который я ссылаюсь. Закомментированные части были только мной, пытающимся найти, где произошла ошибка:
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
#include <ctime>
#include <cstdlib>
#include <string>
#include <cstring>
#include <stdio.h>
using namespace std;
vector<string> bigDeck;
vector<string> cardDeck;
vector<string> playerHand;
vector<string> computerhand;
vector<string> shortvec;
const int DEAL_CARDS = 5;void ResetDeck();
void Shuffle();
void DealACard();
void DealQCard();
void DealBCard();
string CStr(int);
int letsee2;
int main()
{cout << "Ready to play (y/n)? ";
char yn;
cin >> yn;
if (yn == 'n' || yn != 'y') return 0;
ResetDeck();
srand(time(0));
Shuffle();
for (int f=0; f < 10; f++)
{
cout << cardDeck[f] << " ";
}cout << "nnHere's your cards: ";
for (int i=0; i < DEAL_CARDS; i++)
{
DealACard();
cout << playerHand[i] << " ";
}
cout<<"nnHere's the Computer's cards: ";
for (int k=0; k < DEAL_CARDS; k++)
{
DealBCard();
cout << computerhand[k] << " ";
}
for (int u=0; u < DEAL_CARDS; u++)
{
DealQCard();
}
cout<<shortvec.size()<<endl;
cout<<endl<<endl;
//do
//{
for (int woh=0; woh < DEAL_CARDS; woh++)
{
if ((playerHand[woh][0]=='A') && (computerhand[woh][0]=='A'))
{
cout<<"War!"<<endl;}
else if ((playerHand[woh][0]=='A') && (computerhand[woh][0]!='A'))
{
cout<<"Player wins"<<endl;
/*playerHand.push_back(computerhand[woh]);
computerhand.erase(computerhand.begin()+(woh-1));*/
}
else if ((playerHand[woh][0]!='A') && (computerhand[woh][0]=='A'))
{
cout<<"Computer Wins"<<endl;
/*computerhand.push_baci(playerHand[woh]);
playerHand.erase(playerHand.begin()+(woh-1));*/
}
else
{
if ((atoi(playerHand[woh].c_str())) > (atoi(computerhand[woh].c_str())))
{
cout<<"Player wins!"<<endl;
/*playerHand.push_back(computerhand[woh]);
computerhand.erase(computerhand.begin()+(woh-1));*/
}
else if ((atoi(playerHand[woh].c_str())) < (atoi(computerhand[woh].c_str())))
{
cout<<"Computer wins!"<<endl;
/*computerhand.push_back(playerHand[woh]);
playerHand.erase(playerHand.begin()+(woh-1));*/
}
else
{
cout<<"War!"<<endl;
}
}
/*if (playerHand.size() > computerhand.size())
shortvec = computerhand;
else
shortvec = playerHand;
cout<<endl<<endl;
*/
}
/*for (int z=0; z < playerHand.size(); z++)
{
cout << playerHand[z] << " ";
}
cout<<"nnHere's the Computer's cards: ";
for (int y=0; y < computerhand.size(); y++)
{
cout << computerhand[y] << " ";
}*/
cout<<endl<<endl;
//}
//while(((playerHand.size())!=10) || (computerhand.size())!=10);
return 0;
}
void Shuffle()
{
random_shuffle(cardDeck.begin(),cardDeck.end());
}
void DealBCard()
{
computerhand.push_back(cardDeck[0]);
cardDeck.erase(cardDeck.begin());
}
void DealACard()
{
playerHand.push_back(cardDeck[0]);
cardDeck.erase(cardDeck.begin());
}
void DealQCard()
{
shortvec.push_back(bigDeck[0]);
bigDeck.erase(bigDeck.begin());
}
string CStr(int n)
{
stringstream s;
s << n;
return s.str();
}
void ResetDeck()
{
cardDeck.clear();
playerHand.clear();
computerhand.clear();
for (int i=2; i<6; ++i)
{
cardDeck.push_back(CStr(i) + "H");
cardDeck.push_back(CStr(i) + "C");
}
cardDeck.push_back("AH");
cardDeck.push_back("AC");
}
3
Решение
У тебя есть std::vector
называется bigDeck
И в DealQCard
вы пытаетесь получить доступ к его 0-му элементу, несмотря на то, что он не имеет элементов. Вы хотели положить несколько карт в bigDeck
?
4
Другие решения
Попытка получить доступ к несуществующей памяти или памяти, которая используется другим процессом, также вызывает ошибку сегментации (сбрасывается ядро).
Ядро сброшено означает, что состояние программы было записано, то есть его ресурсы были в памяти и процессоре.
2
Загрузка…