Faute de Segmentation 139 (core dumped) C++ après un changement de système d'exploitation
J'ai eu un programme de travail pour l'analyse des données en C++, qui a produit quelque chose comme 35 succès de fichiers de données à jour. Je travaillais sur Scientific Linux, dans le Code:Blocks quand il était au travail et à l'exception de quelques petites erreurs impliquant de très grandes tailles de grille (1000x1000+) il a fonctionné parfaitement et produit exactement ce que je cherchais.
J'ai récemment passé à Ubuntu et attendu qu'il fonctionne bien et il n'a pas. Il accepte la saisie initiale (la première particule switch) mais puis se bloque immédiatement avec une erreur de segmentation 139. J'ai essayé de l'exécuter dans Windows, par contre, avec mon dual boot, mais il ne semble pas reconnaître le local d'un système de dépôt donc, je suis obligé de demander de l'aide.
C'est un programme long donc je vais reproduire la totalité de la chose. Je m'excuse à l'avance.
//This program converts the column output of a 1D PIC code into a workable solution
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
double calculateXMaximum(double arraymax[], int size)
{
double maximum = 0;
for (int k = 1; k < size/2; k++)
{
if(arraymax[2*k] > maximum)
{
maximum = arraymax[2*k];
}
}
return maximum;
}
double calculateXMinimum(double arraymin[], int size)
{
double minimum = 0;
for (int k = 1; k < size/2; k++)
{
if(arraymin[2*k] < minimum)
{
minimum = arraymin[2*k];
}
}
return minimum;
}
double calculatePXMaximum(double arraymax[], int size)
{
double maximum = 0;
for (int k = 1; k < size/2; k++)
{
if(arraymax[2*k+1] > maximum)
{
maximum = arraymax[2*k+1];
}
}
return maximum;
}
double calculatePXMinimum(double arraymin[], int size)
{
double minimum = 0;
for (int k = 1; k < size/2; k++)
{
if(arraymin[2*k+1] < minimum)
{
minimum = arraymin[2*k+1];
}
}
return minimum;
}
int main()
{
//Variables settable before running program - will set up initialisation later.
double xmin = 0;
double xmax = 0;
double pmin = 0;
double pmax = 0;
int xni = 0;
double xntemp = 0;
double deltax = 0;
int xi; //X interpolates, defined from console for resolution of diagram
int pnj = 0;
double pntemp = 0;
double deltap = 0;
int pi;
int type;
double modifier;
//Determines momentum modifier!
cout << "For particle type, enter 1 (e-) or 2 (p+)" << endl;
cout << "Particle type: ";
cin >> type;
if (type == 2)
{
modifier = 1836;
}
else
{
modifier = 1;
}
ifstream inputFile;
ofstream outputFile;
inputFile.open ("/home/Nick/fi020000.dat");
outputFile.open ("/home/Nick/fi20k.dat");
int dataformat[2];
for(int rd = 0; rd < 2; rd++)
{
dataformat[rd] = 0;
inputFile >> dataformat[rd];
}
int records = dataformat[1] + 2;
double data[records];
cout << "Number of particles: " << dataformat[1]/2 << endl;
//Introduction of data from input data file loop. Produces records.
for (int count = 0; count < records; count++)
{
inputFile >> data[count];
}
//Calling functions for xmin and xmax. May streamline later
xmax = calculateXMaximum(data, records) * 1.1;
cout << "Maximum x value: " << xmax << endl;
xmin = calculateXMinimum(data, records) * 1.1;
cout << "Minimum x value: " << xmin << endl;
pmax = calculatePXMaximum(data, records) * 1.1 / modifier;
cout << "Maximum p value: " << pmax << endl;
pmin = calculatePXMinimum(data, records) * 1.1 / modifier;
cout << "Minimum p value: " << pmin << endl;
//Definition of bin size
cout << "Entire desired number of x bins: ";
cin >> xi;
const int xip = xi;
cout << "Enter desired number of p bins: ";
cin >> pi;
const int pip = pi;
cout << "Grid is " << xip << " x " << pip << endl;
//Calculate DELTA X and DELTA P
deltax = (xmax - xmin)/(xip);
deltap = (pmax - pmin)/(pip);
cout << "Resolution of x: " << deltax << endl;
cout << "Resolution of p: " << deltap << endl;
int phaseSpace [xip][pip];
for(int i=0; i<xip; i++)
{
for(int j=0; j<pip; j++)
{
phaseSpace[i][j] = 0;
}
}
for (int phasecount=1; phasecount < (records/2)-1; phasecount++)
{
xntemp = (data[2*phasecount] - xmin)/deltax;
xni = floor(xntemp);
pntemp = ((data[(2*phasecount)+1] / modifier) - pmin)/deltap;
pnj = floor(pntemp);
phaseSpace[xni][pnj] = phaseSpace[xni][pnj] + 1;
}
for (int xoutcount = 0; xoutcount < xip; xoutcount++)
{
for (int poutcount = 0; poutcount < pip; poutcount++)
{
outputFile << xmin+((xoutcount+0.5)*deltax) << " " << pmin+((poutcount+0.5)*deltap) << " "<< phaseSpace[xoutcount][poutcount] << endl;
}
outputFile << endl;
}
cout << "Program complete" << endl;
return 0;
}
Mon intention était de terminer une page 30 rapport de ce week-end et maintenant le programme que j'ai utilisé pour ce faire est complètement effondré. Je ne suis pas informaticien, je suis un physicien et j'ai appris le C++ a moins d'un mois. En tant que tel, je n'ai aucune idée de ce qu'il se passe. Je sais que ce sujet a été vu beaucoup, mais je ne peux pas vraiment comprendre le conseil.
EDIT: trace de la Pile est:
#0 0x4010af ?? () (??:??)
#1 0x7ffff7215ea5 __libc_start_main() (/lib/x86_64-linux-gnu/libc.so.6:??)
#2 0x4017f1 ?? () (??:??)
EDIT2: Valgrind résultats
==4089== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==4089== Command: ./Analysis
==4089==
For particle type, enter 1 (e-) or 2 (p+)
Particle type: 2
==4089== Warning: client switching stacks? SP change: 0x7fefff9c0 --> 0x7fe6d7118
==4089== to suppress, use: --max-stackframe=9603240 or greater
==4089== Invalid write of size 8
==4089== at 0x4010AF: ??? (in /home/paladin/Contour/Analysis/bin/Release/Analysis)
==4089== by 0x5673EA4: (below main) (libc-start.c:260)
==4089== Address 0x7fe6d7118 is on thread 1's stack
==4089==
==4089==
==4089== Process terminating with default action of signal 11 (SIGSEGV)
==4089== Access not within mapped region at address 0x7FE6D7118
==4089== at 0x4010AF: ??? (in /home/paladin/Contour/Analysis/bin/Release/Analysis)
==4089== If you believe this happened as a result of a stack
==4089== overflow in your program's main thread (unlikely but
==4089== possible), you can try to increase the size of the
==4089== main thread stack using the --main-stacksize= flag.
==4089== The main thread stack size used in this run was 8388608.
==4089==
==4089== Process terminating with default action of signal 11 (SIGSEGV)
==4089== Access not within mapped region at address 0x7FE6D7111
==4089== at 0x4A256A0: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==4089== If you believe this happened as a result of a stack
==4089== overflow in your program's main thread (unlikely but
==4089== possible), you can try to increase the size of the
==4089== main thread stack using the --main-stacksize= flag.
==4089== The main thread stack size used in this run was 8388608.
==4089==
==4089== HEAP SUMMARY:
==4089== in use at exit: 17,520 bytes in 4 blocks
==4089== total heap usage: 4 allocs, 0 frees, 17,520 bytes allocated
==4089==
==4089== LEAK SUMMARY:
==4089== definitely lost: 0 bytes in 0 blocks
==4089== indirectly lost: 0 bytes in 0 blocks
==4089== possibly lost: 0 bytes in 0 blocks
==4089== still reachable: 17,520 bytes in 4 blocks
==4089== suppressed: 0 bytes in 0 blocks
==4089== Rerun with --leak-check=full to see details of leaked memory
==4089==
==4089== For counts of detected and suppressed errors, rerun with: -v
==4089== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Segmentation fault (core dumped)
L'erreur se produit à la ifstream inputFile déclaration.
EDIT3: Comme demandé, session de console:
paladin@paladin:~/Programming/Contour Constructor 2/bin/Debug$ ./Contour\ Constructor\ 2
For particle type, enter 1 (e-) or 2 (p+)
Particle type: 2
Segmentation fault (core dumped)
Il y a 1200402 lignes dans le fichier d'entrée, correspondant à 600200 particules dans le PIC code plus 2 descriptif des lignes.
EDIT4: Complète tir dans le noir ici mais j'ai d'abord compilé sous GCC 4.4.7 Scientifiques Linux. Je suis maintenant à l'aide de la dernière version Ubuntu (4.8.1). A quelque chose de changé dans l'intervalle qui invaliderait la taille du fichier que j'utilise?
Avez-vous recompiler sous Ubuntu?
valgrind prog arg arg
aussi utiles.avez-vous recompiler? avez-vous l'exécutez dans un débogueur?
(2) s'il vous Plaît, toujours initialiser vos variables. Je ressens de la douleur quand je lis des choses comme
int xi
; ou int pi;
.
OriginalL'auteur Nicholas Millington | 2013-09-12
Vous devez vous connecter pour publier un commentaire.
La grande astuce ici est que valgrind pense que vous êtes de commutation threads-et certainement à partir du code que vous avez indiqué, vous n'êtes pas l'utilisation de plusieurs threads. Étant donné que chaque thread dans un programme multithread a sa propre pile, valgrind suppose que si le pointeur de pile changements par plus d'un certain seuil (voir --max-structure de pile comme indiqué dans le valgrind de sortie) que vous passez à un autre thread.
Dans la réalité, ce qui se passe est que vous avez créé un ÉNORME bloc de pile, 9603240 octets pour être exact. Cela dépasse les 8 mo ou alors que vous êtes probablement obtenir par défaut. Vous pouvez voir la limite douce en regardant dans un shell:
En d'autres termes, la pile est limitée à 8 mo. Si vous dépassez cette limite, Linux va supposer quelque chose de mal(tm) est arrivé et mettre fin à votre processus.
Un correctif immédiat vous pouvez utiliser est d'augmenter la limite, ou tout simplement à un nombre illimité de:
Cela devrait arrêter votre processus à partir de la plante, ce qui explique pourquoi il a bien fonctionné sur une boîte et pas un autre (celui d'où il a travaillé en avaient probablement plus la taille de la pile de la limite définie par défaut).
Maintenant, à partir d'une conception de point de vue, il est généralement un mauvaise idée pour créer une pile cadres de cette grande. Pour les grandes allocations, vous devez utiliser un segment de mémoire, donc quelque chose comme:
pourrait être remplacé par
qui alloue et libère la mémoire dans le tas à la place. Cela vous permettra d'éviter de tels problèmes en premier lieu. Ou, vous pouvez toujours utiliser l'une des conteneurs standard comme std::vector<> " au lieu d'éviter la question.
J'ai mis en place XDEBUG sur HHVM et d'avoir gardé ce vidage de la mémoire d'erreur sur mon Linux Mint boîte, lorsque j'ai fait le débogueur. Merci!!!!!! Ce changement de paramètre fixe le problème. Je n'avais pas hâte à la chasse au bug dans le massif HHVM base de code.
OriginalL'auteur FatalError
Si vous voyez ce problème seulement pour les grandes entrée tailles, les chances sont que vous obtenez un débordement de la pile lors de la création de
phaseSpace
, car cela pourrait être un très grand tableau. Si vous utilisez unstd::vector
au lieu de la simple tableau, ce problème devrait être évité:Le reste de votre code fonctionne probablement la même chose avec le vecteur.
Sinon, si
xni
etpni
sortir des limites du terrain, vous permettra de remplacer la mémoire vive. Vous pouvez ajouter de sortie des états de compte pour ces valeurs et de voir si quelque chose semble faux.vous devez également utiliser un std::vector<double> pour votre tableau de données. std::vector alloue sur le tas, tandis que les tableaux que vous utilisez actuellement allouer sur la pile. Il n'y a plus de segment de pile. Aussi, vous devez spécifier la capacité des vecteurs lorsque vous les créez à éviter de coûteuses opérations de redimensionnement.
Merci beaucoup. Je vais régler cette question demain matin.
OriginalL'auteur sth
Je suis surpris de ce programme, même compile: vous devez déclarer des tableaux de taille qui ne peut pas être déterminé au cours de la compilation, comme ci-dessous. Pourriez-vous dire le compilateur que vous utilisez?
roulette russe"?
href="http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html" >gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
Format[] contient à la fois le timestep de l'information de l'origine de la forme et du nombre de particules présentes à l'intérieur de la simulation. Format[1] contient le nombre d'enregistrements attendu, -2 en raison du PIC de code que j'utilise.
OriginalL'auteur Michael
C'est ce à quoi il pourrait ressembler à utiliser std::vector au lieu de natif de tableaux.
J'ai enlevé une partie de la
std::endl
appels et de les remplacer par"\n"
afin d'éviter d'I/O de la mémoire tampon de rinçage.J'ai fait une légère modification de la façon dont votre de min et max sont calculées.
J'ai déménagé quelques déclarations de variables et leur fit
const
si possible.Important: Vous devriez vérifier l'état de votre
ifstream
comme vous êtes la lecture de l'entrée. Comme il est, vous avez pu lire au delà de la fin du fichier et de ne jamais le savoir. Il semble également y avoir un malentendu sur le contenu de votredata
tableau. Il semble que vous pensez qu'il contient vos deux principaux descriptif lignes. Cependant, vous avez déjà tiré ces deux numéros à partir du flux dansdataformat
, de sorte que vous n'avez pas besoin de compte pour eux.Un très petit jeu de la main vérifié test d'entrée et de sortie de données serait utile.
OriginalL'auteur Adam Burry