Seg Fault using stacks and queues - c++

I am new to using stacks and queues and I am having memory problems. Could you give me a little insight in what I am doing wrong? This is supposed to be an implementation of a war game using stacks and queues.
#ifndef WAR_H
#define WAR_H
/*
This runWar function runs a game of war between 2 automated players
and returns the number of rounds (both put a card down
once per round) until someone won. An integer is given
as an upper limit to how many rounds a game can go on for.
*/
#include <iostream>
#include <stdlib.h>
#include <stdexcept>
#include <stack>
#include <queue>
#include "deck.h"
using namespace std;
int decide(Card, Card, unsigned int&);
int runWar(unsigned int limit)
{
Deck d;
queue<Card> p1;
queue<Card> p2;
while(d.size() != 0)
{
p1.push(d.getTopCard());
if(d.size() != 0)
{
p2.push(d.getTopCard());
}
}
bool winner = false; //checks if anyone won
unsigned int roundcount = 0; //checks number of comparisons
while(roundcount<limit && winner == false)
{
Card one = p1.front();
Card two = p2.front();
p1.pop();
p2.pop();
if(one.getRank() > two.getRank())
{
roundcount++;
p1.push(one);
p1.push(two);
}
else if(one.getRank() < two.getRank())
{
roundcount++;
p2.push(one);
p2.push(two);
}
else
{
stack<Card> pile;
//3 cards off the top each
bool war_done = false;
while(war_done == false)
{
for(unsigned int w=0; w<3; w++)
{
pile.push(p1.front());
pile.push(p2.front());
p1.pop();
p2.pop();
}
Card p11 = p1.front();
Card p22 = p2.front();
pile.push(p11);
pile.push(p22);
p1.pop();
p2.pop();
if(p11.getRank() > p22.getRank())
{
roundcount++;
while(!(pile.empty()))
{
p1.push(pile.top());
pile.pop();
}
p1.push(one);
p1.push(two);
war_done = true;
}
else if(p11.getRank() > p22.getRank())
{
roundcount++;
while(!(pile.empty()))
{
p2.push(pile.top());
pile.pop();
}
p2.push(one);
p2.push(two);
war_done = true;
}
}
if(p1.empty() || p2.empty())
{
winner = true;
}
}
}
return roundcount;
}
#endif
int main()
{
for(unsigned int i=0; i<19; i++)
{
cout<<runWar(1000)<<endl;
}
return 0;
}
My card and deck classes work find. getTopCard() is basically a pop that returns the top card. getRank() says if it is a 2-Ace. Also, the int main() is in the driver.cpp file.
Valgrind Output:
==3942== Memcheck, a memory error detector
==3942== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3942== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==3942== Command: ./doWar
==3942==
==3942== Conditional jump or move depends on uninitialised value(s)
==3942== at 0x4023BA: runWar(unsigned int) (war.h:77)
==3942== by 0x4016F6: main (doWar.cpp:18)
==3942==
==3942== Conditional jump or move depends on uninitialised value(s)
==3942== at 0x40201B: runWar(unsigned int) (war.h:45)
==3942== by 0x4016F6: main (doWar.cpp:18)
==3942==
==3942== Use of uninitialised value of size 8
==3942== at 0x401FCD: runWar(unsigned int) (war.h:41)
==3942== by 0x4016F6: main (doWar.cpp:18)
==3942==
==3942== Invalid read of size 4
==3942== at 0x401FCD: runWar(unsigned int) (war.h:41)
==3942== by 0x4016F6: main (doWar.cpp:18)
==3942== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==3942==
==3942==
==3942== Process terminating with default action of signal 11 (SIGSEGV)
==3942== Access not within mapped region at address 0x0
==3942== at 0x401FCD: runWar(unsigned int) (war.h:41)
==3942== by 0x4016F6: main (doWar.cpp:18)
==3942== If you believe this happened as a result of a stack
==3942== overflow in your program's main thread (unlikely but
==3942== possible), you can try to increase the size of the
==3942== main thread stack using the --main-stacksize= flag.
==3942== The main thread stack size used in this run was 8388608.
==3942==
==3942== HEAP SUMMARY:
==3942== in use at exit: 1,728 bytes in 6 blocks
==3942== total heap usage: 33 allocs, 27 frees, 8,952 bytes allocated
==3942==
==3942== LEAK SUMMARY:
==3942== definitely lost: 0 bytes in 0 blocks
==3942== indirectly lost: 0 bytes in 0 blocks
==3942== possibly lost: 0 bytes in 0 blocks
==3942== still reachable: 1,728 bytes in 6 blocks
==3942== suppressed: 0 bytes in 0 blocks
==3942== Rerun with --leak-check=full to see details of leaked memory
==3942==
==3942== For counts of detected and suppressed errors, rerun with: -v
==3942== Use --track-origins=yes to see where uninitialised values come from
==3942== ERROR SUMMARY: 31 errors from 4 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

Before every 'pop()' check wheather it is empty or not like
If(!p1.empty()){
p1.pop();
}

Related

C++ valgrind error message segmentation fault

I'm new to C++ and I'm trying to write an enigma machine simulator. I know I've done something funky with my pointers and I've run it through Valgrind, but I'm not sure what the error messages mean and where to begin fixing it? (What does suppressed mean in the leak summary?)
Here's part of the code where each component is created and where the error occurs.
Enigma::Enigma(int argc, char** argv){
errorCode = NO_ERROR;
plugboard = NULL;
*rotor = NULL; //WHERE THE ERROR OCCURS
reflector = NULL;
rotorCount = 0;
//first check how many rotors there are
if (argc >= 5)
rotorCount = argc - 4;
if (argc <= 4)
errorCode = INSUFFICIENT_NUMBER_OF_PARAMETERS;
//pass files into each component and check if well-formed
if (errorCode == NO_ERROR){
plugboard = new Plugboard(argv[1]);
errorCode = plugboard -> errorCode;
if (errorCode == NO_ERROR){
cout << "Plugboard configuration loaded successfully" << endl;
reflector = new Reflector(argv[2]);
errorCode = reflector -> errorCode;
if (errorCode == NO_ERROR){
cout << "Reflector configuration loaded successfully" << endl;
rotor = new Rotor*[rotorCount];
size_t i = 0;
while (i < rotorCount && errorCode == NO_ERROR) {
rotor[i] = new Rotor (argv[i+3]);
i++;
errorCode = rotor[i]-> errorCode;
//destructor if rotor loading was unsuccessful
if (errorCode != NO_ERROR){
for (int j=0; j<=i; j++)
delete rotor[j];
delete [] rotor;
Here's the Valgrind error message:
reflectors/I.rf rotors/I.rot rotors/II.rot rotors/III.rot rotors/I.pos
==68943== Memcheck, a memory error detector
==68943== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==68943== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==68943== Command: ./enigma plugboards/I.pb reflectors/I.rf rotors/I.rot rotors/II.rot rotors/III.rot rotors/I.pos
==68943==
--68943-- run: /usr/bin/dsymutil "./enigma"
==68943== Use of uninitialised value of size 8
==68943== at 0x100002598: Enigma::Enigma(int, char**) (enigma.cpp:17)
==68943== by 0x100002F92: Enigma::Enigma(int, char**) (enigma.cpp:12)
==68943== by 0x100000862: main (main.cpp:18)
==68943== Uninitialised value was created by a stack allocation
==68943== at 0x1000007D4: main (main.cpp:11)
==68943==
==68943== Invalid write of size 8
==68943== at 0x100002598: Enigma::Enigma(int, char**) (enigma.cpp:17)
==68943== by 0x100002F92: Enigma::Enigma(int, char**) (enigma.cpp:12)
==68943== by 0x100000862: main (main.cpp:18)
==68943== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==68943==
==68943==
==68943== Process terminating with default action of signal 11 (SIGSEGV)
==68943== Access not within mapped region at address 0x0
==68943== at 0x100002598: Enigma::Enigma(int, char**) (enigma.cpp:17)
==68943== by 0x100002F92: Enigma::Enigma(int, char**) (enigma.cpp:12)
==68943== by 0x100000862: main (main.cpp:18)
==68943== If you believe this happened as a result of a stack
==68943== overflow in your program's main thread (unlikely but
==68943== possible), you can try to increase the size of the
==68943== main thread stack using the --main-stacksize= flag.
==68943== The main thread stack size used in this run was 10022912.
==68943==
==68943== HEAP SUMMARY:
==68943== in use at exit: 18,685 bytes in 166 blocks
==68943== total heap usage: 187 allocs, 21 frees, 27,133 bytes allocated
==68943==
==68943== LEAK SUMMARY:
==68943== definitely lost: 0 bytes in 0 blocks
==68943== indirectly lost: 0 bytes in 0 blocks
==68943== possibly lost: 72 bytes in 3 blocks
==68943== still reachable: 200 bytes in 6 blocks
==68943== suppressed: 18,413 bytes in 157 blocks
==68943== Rerun with --leak-check=full to see details of leaked memory
==68943==
==68943== For counts of detected and suppressed errors, rerun with: -v
==68943== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 1 from 1)
Segmentation fault: 11
Thanks
Maybe you should take a look at: How do pointer to pointers work in C?
Basically, I see that rotor is a pointer to pointer or possibly an array of pointers (since you initialize *rotor to NULL and later also set rotor[i] = new Rotor).
Make sure you've initialized rotor properly. Is it pointing to a valid object? If not, you cannot expect *rotort = NULL /* or whatever value */; to work.
Basically suppressed means the memory leaks outside of your code in shared libraries.And *rotor = NULL,but it doesn't point to any valid object..

Memory leak when using regex.h?

Minimal code example is as follows:
#include <cstdlib>
#include <iostream>
#include <vector>
#include <regex.h>
using namespace std;
class regex_result {
public:
/** Contains indices of starting positions of matches.*/
std::vector<int> positions;
/** Contains lengths of matches.*/
std::vector<int> lengths;
};
regex_result match_regex(string regex_string, const char* string) {
regex_result result;
regex_t* regex = new regex_t;
regcomp(regex, regex_string.c_str(), REG_EXTENDED);
/* "P" is a pointer into the string which points to the end of the
previous match. */
const char* pointer = string;
/* "n_matches" is the maximum number of matches allowed. */
const int n_matches = 10;
regmatch_t matches[n_matches];
int nomatch = 0;
while (!nomatch) {
nomatch = regexec(regex, pointer, n_matches, matches, 0);
if (nomatch)
break;
for (int i = 0; i < n_matches; i++) {
int start,
finish;
if (matches[i].rm_so == -1) {
break;
}
start = matches[i].rm_so + (pointer - string);
finish = matches[i].rm_eo + (pointer - string);
result.positions.push_back(start);
result.lengths.push_back(finish - start);
}
pointer += matches[0].rm_eo;
}
delete regex;
return result;
}
int main(int argc, char** argv) {
string str = "this is a test";
string pat = "this";
regex_result res = match_regex(pat, str.c_str());
cout << res.positions.size() << endl;
return 0;
}
So I have written a function that parses a given string for regular expression matches. The result is held in a class that is essentially two vectors, one for the positions of the matches and one for the corresponding match lengths.
This works fine, but when I ran valgrind over it, it shows some substantial memory leaks.
When using valgrind --leak-check=full on the code above I get:
==24843== Memcheck, a memory error detector
==24843== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==24843== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==24843== Command: ./test
==24843==
1
==24843==
==24843== HEAP SUMMARY:
==24843== in use at exit: 11,688 bytes in 37 blocks
==24843== total heap usage: 54 allocs, 17 frees, 12,868 bytes allocated
==24843==
==24843== 256 bytes in 1 blocks are definitely lost in loss record 14 of 18
==24843== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24843== by 0x543549A: regcomp (regcomp.c:487)
==24843== by 0x400ED0: match_regex(std::string, char const*) (in <path>)
==24843== by 0x4010CA: main (in <path>)
==24843==
==24843== 11,432 (224 direct, 11,208 indirect) bytes in 1 blocks are definitely lost in loss record 18 of 18
==24843== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24843== by 0x4C2CF1F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24843== by 0x5434BAF: re_compile_internal (regcomp.c:760)
==24843== by 0x54354FF: regcomp (regcomp.c:506)
==24843== by 0x400ED0: match_regex(std::string, char const*) (in <path>)
==24843== by 0x4010CA: main (in <path>)
==24843==
==24843== LEAK SUMMARY:
==24843== definitely lost: 480 bytes in 2 blocks
==24843== indirectly lost: 11,208 bytes in 35 blocks
==24843== possibly lost: 0 bytes in 0 blocks
==24843== still reachable: 0 bytes in 0 blocks
==24843== suppressed: 0 bytes in 0 blocks
==24843==
==24843== For counts of detected and suppressed errors, rerun with: -v
==24843== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Is my code wrong or is there really a bug in those files?
Your regex_t management is not required to be dynamic, and though that isn't directly related to you problem, it is a little odd. The real problem is you never regfree() your resulting expression if compiled successfully (which you should verify). You should setup your regular expression like this:
regex_t regex;
int res = regcomp(&regex, regex_string.c_str(), REG_EXTENDED);
if (res == 0)
{
// use your expression via &regex
....
// and eventually free it when done.
regfree(&regex);
}
If your implementation supports them, I strongly advise using the C++11 provided <regex> library, as it has nice RAII solutions to much of this.
You must call regfree() to free memory allocated by regcomp().

GMP mpf functions causing a segmentation fault

I can not figure out that is causing this error. I just installed GMP on ubuntu. This is a 64 bit OS on an AMD cpu (not sure if it matters). I keep getting a segmentation fault.
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <time.h>
int main(int argc, char** argv)
{
mpz_t sum, fac;
mpf_t fsum, ffac;
int i;
time_t t;
mpz_init_set_ui(sum, 1);
mpz_init_set_ui(fac, 1);
t = time(NULL);
for(i = 10000; i >= 1; --i)
{
mpz_mul_ui(fac, fac, i);
mpz_add(sum, sum, fac);
if(i % 10000 == 0)
{
printf("%d\n", i);
}
}
printf("Time %d\n", (time(0) - t));
mpf_init(fsum);
mpf_init(ffac);
mpf_set_z(fsum, sum);
mpf_set_z(ffac, fac);
mpz_clear(sum);
mpz_clear(fac);
mpf_div(fac, sum, fac);
mpf_out_str(stdout, 10, 50, fac);
mpf_clear(fsum);
mpf_clear(ffac);
return(EXIT_SUCCESS);
}
This code outputs the following...
10000
Time 0
Segmentation fault (core dumped)
I then tried to run this program with valgrind and this is the output.
==25427== Memcheck, a memory error detector
==25427== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25427== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==25427== Command: /home/chase/NetBeansProjects/GmpECalc/dist/Debug/GNU-Linux-x86/gmpecalc
==25427==
10000
Time 1
==25427== Invalid read of size 8
==25427== at 0x4E8E590: __gmpn_copyi (in /usr/lib/x86_64-linux-gnu/libgmp.so.10.1.3)
==25427== by 0x400B27: main (main.c:40)
==25427== Address 0x73b0000073c is not stack'd, malloc'd or (recently) free'd
==25427==
==25427==
==25427== Process terminating with default action of signal 11 (SIGSEGV)
==25427== Access not within mapped region at address 0x73B0000073C
==25427== at 0x4E8E590: __gmpn_copyi (in /usr/lib/x86_64-linux-gnu/libgmp.so.10.1.3)
==25427== by 0x400B27: main (main.c:40)
==25427== If you believe this happened as a result of a stack
==25427== overflow in your program's main thread (unlikely but
==25427== possible), you can try to increase the size of the
==25427== main thread stack using the --main-stacksize= flag.
==25427== The main thread stack size used in this run was 8388608.
==25427==
==25427== HEAP SUMMARY:
==25427== in use at exit: 48 bytes in 2 blocks
==25427== total heap usage: 3,706 allocs, 3,704 frees, 27,454,096 bytes allocated
==25427==
==25427== LEAK SUMMARY:
==25427== definitely lost: 0 bytes in 0 blocks
==25427== indirectly lost: 0 bytes in 0 blocks
==25427== possibly lost: 0 bytes in 0 blocks
==25427== still reachable: 48 bytes in 2 blocks
==25427== suppressed: 0 bytes in 0 blocks
==25427== Rerun with --leak-check=full to see details of leaked memory
==25427==
==25427== For counts of detected and suppressed errors, rerun with: -v
==25427== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
The error seems to be occurring at the mpf_div function. However, if I remove this function the error will occur at mpf_out_str. I also tried initializing ffac and fsum to doubles (instead of setting them to the fac and sum) and I get the same error.
Problem is in this lines:
mpz_clear(sum); // You clear the variables, GMP deallocates their memory
mpz_clear(fac);
mpf_div(fac, sum, fac); // You use cleared variables, segfault
Maybe you meant:
mpf_div(ffac, fsum, ffac);

push_back a pointer of object results in segfault

The following code is to move the "non-overlapping" TablePath from vector v to vector u. I am encountering segmentaion fault at the line "u.push_back(*it1);". I didn't copy the object(but instead only copy the pointer of the object) so I believe the problem doesn't lie in copying constructor. Can you give some hints on why segfault is occuring ?
#include <iostream>
#include <vector>
using namespace std;
class TablePath
{
private:
int source;
int destination;
public:
TablePath(int,int);
~TablePath();
int overlap(TablePath*);
void toString();
TablePath(const TablePath& that) : source(that.source), destination(that.destination)
{
}
};
TablePath::TablePath(int source=0,int destination=0)
{
this->source = source;
this->destination = destination;
}
int TablePath::overlap(TablePath* thatTablePath)
{
if (this->source >= thatTablePath->source and this->source <= thatTablePath->destination)
return 1;
else if (this->destination >= thatTablePath->source and this->destination <= thatTablePath->destination)
return 1;
else if (thatTablePath->source >= this->source and thatTablePath->source <= this->destination)
return 1;
else if (thatTablePath->destination >= this->source and thatTablePath->destination <= this->destination)
return 1;
else
return 0;
}
void TablePath::toString()
{
cout << this->source << " " << this->destination << endl;
}
int main()
{
int numofTests;
cin >> numofTests;
while(numofTests > 0)
{
int numofMoves;
vector<TablePath *> v;
cin >> numofMoves;
for (int i=0;i<numofMoves;i++)
{
int source,destination;
cin >> source >> destination;
TablePath* MyTablePath = new TablePath(source,destination);
v.push_back(MyTablePath);
}
vector<TablePath *> u;
vector<TablePath *>::iterator it1 = v.begin();
u.push_back(*it1);
v.erase(v.begin());
for(vector<TablePath *>::iterator it1 = v.begin(); it1 != v.end(); ++it1)
{
for(vector<TablePath *>::iterator it2 = u.begin(); it2 != u.end(); ++it2)
{
if ((*it1)->overlap((*it2)))
{
u.push_back(*it1);
}
}
}
cout << u.size() * 10;
v.erase(v.begin(),v.end());
u.erase(u.begin(),u.end());
numofTests--;
}
}
The following is the output I get from valgrind:
frank#frank-vm:~$ valgrind --tool=memcheck ./tablepath
==6172== Memcheck, a memory error detector
==6172== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==6172== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==6172== Command: ./tablepath
==6172==
1
3
10
20
15 30
20 50
==6172== Invalid read of size 4
==6172== at 0x8048BB0: main (in /home/frank/tablepath)
==6172== Address 0x4320184 is 0 bytes after a block of size 4 free'd
==6172== at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==6172== by 0x8049616: __gnu_cxx::new_allocator<TablePath*>::deallocate(TablePath**, unsigned int) (in /home/frank/tablepath)
==6172== by 0x80493E8: std::_Vector_base<TablePath*, std::allocator<TablePath*> >::_M_deallocate(TablePath**, unsigned int) (in /home/frank/tablepath)
==6172== by 0x8049230: std::vector<TablePath*, std::allocator<TablePath*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<TablePath**, std::vector<TablePath*, std::allocator<TablePath*> > >, TablePath* const&) (in /home/frank/tablepath)
==6172== by 0x8048E00: std::vector<TablePath*, std::allocator<TablePath*> >::push_back(TablePath* const&) (in /home/frank/tablepath)
==6172== by 0x8048BED: main (in /home/frank/tablepath)
==6172==
==6172== Invalid read of size 4
==6172== at 0x8048965: TablePath::overlap(TablePath*) (in /home/frank/tablepath)
==6172== by 0x8048BCA: main (in /home/frank/tablepath)
==6172== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6172==
==6172==
==6172== Process terminating with default action of signal 11 (SIGSEGV)
==6172== Access not within mapped region at address 0x0
==6172== at 0x8048965: TablePath::overlap(TablePath*) (in /home/frank/tablepath)
==6172== by 0x8048BCA: main (in /home/frank/tablepath)
==6172== If you believe this happened as a result of a stack
==6172== overflow in your program's main thread (unlikely but
==6172== possible), you can try to increase the size of the
==6172== main thread stack using the --main-stacksize= flag.
==6172== The main thread stack size used in this run was 8388608.
==6172==
==6172== HEAP SUMMARY:
==6172== in use at exit: 48 bytes in 5 blocks
==6172== total heap usage: 8 allocs, 3 frees, 64 bytes allocated
==6172==
==6172== LEAK SUMMARY:
==6172== definitely lost: 0 bytes in 0 blocks
==6172== indirectly lost: 0 bytes in 0 blocks
==6172== possibly lost: 0 bytes in 0 blocks
==6172== still reachable: 48 bytes in 5 blocks
==6172== suppressed: 0 bytes in 0 blocks
==6172== Rerun with --leak-check=full to see details of leaked memory
==6172==
==6172== For counts of detected and suppressed errors, rerun with: -v
==6172== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
std::vector<T>::push_back is (usually) allowed to invalidate all iterators associated with the vector object. So after you do:
u.push_back(*it1);
it is not safe to continue the inner for loop with ++it2.
You could use an index for the inner loop instead. Or, break out of the inner loop right after doing the push_back, if you don't really want multiple copies of the same TablePath* pointer in u.

Segfault after the return 0;

I would like to use ITK for a simple color-ratio program, but I get a segfault after the return 0; of the main function.
here is my code.
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include <iostream>
#include <string>
#include <vector>
#include "itkRGBPixel.h"
const unsigned int Dimension = 2;
typedef itk::RGBPixel< unsigned char > PixelType;
typedef itk::Image< PixelType, Dimension > ImageType;
typedef itk::ImageFileReader< ImageType > ReaderType;
typedef itk::ImageFileWriter< ImageType > WriterType;
int main(int argc, char** argv)
{
std::string input=argv[1], output=argv[2];
//allocation of the image data
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
reader->SetFileName(input);
writer->SetFileName(output);
reader->Update();
//access image
ImageType::Pointer image = reader->GetOutput();
ImageType::Pointer output_img;
//apparently providing the spacing and origin in ITK is mandatory
ImageType::SpacingType spacing;
spacing[0] = 0.33;
spacing[1] = 0.33;
image->SetSpacing(spacing);
ImageType::PointType origin;
origin[0] = 0.0;
origin[1] = 0.0;
image->SetOrigin(origin);
writer->SetInput( reader->GetOutput() );
writer->Update();
return EXIT_SUCCESS;
}
It compiles and links without any error messages but I have a segfault during execution.
By executing the program line by line using gdb, I pinpionted the segfault to the last line of the program: after return 0;
Here is the backtrace
Program received signal SIGSEGV, Segmentation fault.
0xb79099bc in ?? () from /usr/lib/i386-linux-gnu/libstdc++.so.6
(gdb) bt
#0 0xb79099bc in ?? () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#1 0xb7909a4e in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() ()
from /usr/lib/i386-linux-gnu/libstdc++.so.6
#2 0x08065369 in main (argc=3, argv=0xbffff1b4) at /home/thibault/workspace/OU/MachineLearning/Project1/src/itkTry1.cpp:221
(gdb)
and when checking with valgrind:
==16671== Memcheck, a memory error detector
==16671== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==16671== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==16671== Command: ./ColorRatio clouds2.jpeg coucou.jpeg --track-origins=yes
==16671==
==16671== Conditional jump or move depends on uninitialised value(s)
==16671== at 0x4B28DD8: inflateReset2 (in /lib/i386-linux-gnu/libz.so.1.2.3.4)
==16671== by 0x4B28EC7: inflateInit2_ (in /lib/i386-linux-gnu/libz.so.1.2.3.4)
==16671== by 0x4C87E58: ??? (in /usr/lib/libITKniftiio.so.3.20.1)
==16671==
==16671== Conditional jump or move depends on uninitialised value(s)
==16671== at 0x4B28DD8: inflateReset2 (in /lib/i386-linux-gnu/libz.so.1.2.3.4)
==16671== by 0x4B28EC7: inflateInit2_ (in /lib/i386-linux-gnu/libz.so.1.2.3.4)
==16671==
==16671== Invalid read of size 4
==16671== at 0x47429BC: ??? (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==16671== by 0x47CE4D2: (below main) (libc-start.c:226)
==16671== Address 0xfffffffc is not stack'd, malloc'd or (recently) free'd
==16671==
==16671==
==16671== Process terminating with default action of signal 11 (SIGSEGV)
==16671== Access not within mapped region at address 0xFFFFFFFC
==16671== at 0x47429BC: ??? (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==16671== by 0x47CE4D2: (below main) (libc-start.c:226)
==16671== If you believe this happened as a result of a stack
==16671== overflow in your program's main thread (unlikely but
==16671== possible), you can try to increase the size of the
==16671== main thread stack using the --main-stacksize= flag.
==16671== The main thread stack size used in this run was 8388608.
==16671==
==16671== HEAP SUMMARY:
==16671== in use at exit: 2,352,658 bytes in 63,532 blocks
==16671== total heap usage: 74,071 allocs, 10,539 frees, 14,082,941 bytes allocated
==16671==
==16671== LEAK SUMMARY:
==16671== definitely lost: 49 bytes in 2 blocks
==16671== indirectly lost: 0 bytes in 0 blocks
==16671== possibly lost: 1,309,540 bytes in 42,156 blocks
==16671== still reachable: 1,043,069 bytes in 21,374 blocks
==16671== suppressed: 0 bytes in 0 blocks
==16671== Rerun with --leak-check=full to see details of leaked memory
==16671==
==16671== For counts of detected and suppressed errors, rerun with: -v
==16671== Use --track-origins=yes to see where uninitialised values come from
==16671== ERROR SUMMARY: 5 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
Even with 36000 useless try/catch statments, I still get that same segmentation fault after the main.
Can anyone please help me?
Thank you in advance
This code works for me:
#include <iostream>
#include <string>
#include <vector>
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRGBPixel.h"
int main(int argc, char** argv)
{
std::string input = "/home/doriad/temp/test.png";
std::string output= "output.png";
const unsigned int Dimension = 2;
typedef itk::RGBPixel< unsigned char > PixelType;
typedef itk::Image< PixelType, Dimension > ImageType;
typedef itk::ImageFileReader< ImageType > ReaderType;
typedef itk::ImageFileWriter< ImageType > WriterType;
//allocation of the reader
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(input);
reader->Update();
//access image
ImageType::Pointer image = reader->GetOutput();
// ImageType::Pointer output_img;// This line does nothing
//apparently providing the spacing and origin in ITK is mandatory
// The spacing and origin are read from the file.
// ImageType::SpacingType spacing;
// spacing[0] = 0.33;
// spacing[1] = 0.33;
// image->SetSpacing(spacing);
// ImageType::PointType origin;
// origin[0] = 0.0;
// origin[1] = 0.0;
// image->SetOrigin(origin);
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(output);
writer->SetInput( reader->GetOutput() );
writer->Update();
return EXIT_SUCCESS;
}
Of course, you have to change the 'input' string to a file you actually have.