Неопределённое поведения с сегфолтом
Я разрабатываю программу компьютерного зрения:
#include <iostream>
typedef struct{
unsigned char red;
unsigned char green;
unsigned char blue;
} PixelRGB256;
typedef struct Coordinata{
unsigned int row;
unsigned int col;
} Coordinata;
bool operator!=(Coordinata coord1, Coordinata coord2){
if(coord1.row != coord2.row or coord1.col != coord2.col){return true;}
return false ;
}
Coordinata inc(Coordinata& coord, int rows){
if(coord.row == rows-1){
++coord.col;
coord.row=0;
}else{++coord.row;}
return coord;
}
unsigned int unsignedMinus(unsigned int a, unsigned int b){
if(a < b){return 0;}
return a - b;
}
Coordinata dec(Coordinata& coord, int rows){
if(coord.row == rows-1){
++coord.col;
coord.row=0;
}else{++coord.row;}
return coord;
}
template <typename T, int cols, int rows>
class Matrix{
public:
T matr[cols][rows];
Coordinata end = {1,0};
void append(T element){
if(end.row == rows-1){
++end.col;
end.row=0;
}else{++end.row;}
matr[end.col][end.row] = element;
};
Matrix& operator=(T array[cols][rows]){
for(int col = 0; col < cols; ++col){
for(int row = 0; row < rows; ++row){
matr[col][row] = array[col][row];
};
};
return *this;
};
T index(Coordinata coord){
if(coord.row >= rows or coord.col >= cols){
return {};
};
return matr[coord.col][coord.row];
};
void print(){
for(int col = 0; col < cols; ++col){
for(int row = 0; row < rows; ++row){
std::cout << matr[col][row] << " ";
};
std::cout << std::endl;
};
};
bool inMatrix(T element){
for(int col = 0; col < cols; ++col){
for(int row = 0; row < rows; ++row){
if(row == element){return true;}
};
};
return false;
}
};
bool approx(int a, int b, int range = 10){
if( (a - b) < range or (b - a) < range){return true;}
return false;
}
bool morePixel(PixelRGB256 p1, PixelRGB256 p2, int pass=0){
if(p1.red >= p2.red and p1.green >= p2.green and p1.blue >= p2.blue){
return true;
};
return false;
}
bool lessPixel(PixelRGB256 p1, PixelRGB256 p2, int pass=0){
if(p1.red <= p2.red and p1.green <= p2.green and p1.blue <= p2.blue){
return true;
};
return false;
}
bool equalPixel(PixelRGB256 p1, PixelRGB256 p2, int pass=0){
if(p1.red == p2.red and p1.green == p2.green and p1.blue == p2.blue){return true;};
return false;
}
bool approxPixel(PixelRGB256 p1, PixelRGB256 p2, int threshold){
if(approx(p1.red, p2.red, threshold) and approx(p1.green, p2.green, threshold) and approx(p1.blue, p2.blue, threshold)){return true;}
return false;
}
bool notPixel(PixelRGB256 p1, PixelRGB256 p2, int pass=0){
if(p1.red != p2.red or p1.green != p2.green or p1.blue != p2.blue){return true;}
return false;
}
bool approxnotPixel(PixelRGB256 p1, PixelRGB256 p2, int threshold=10){
if(!(approx(p1.red, p2.red, threshold) and approx(p1.green, p2.green, threshold) and approx(p1.blue, p2.blue, threshold))){return true;}
return false;
}
Matrix<Coordinata, 3, 3> neighbours(Coordinata coord){
Matrix<Coordinata, 3, 3> mat;
for(unsigned int row = unsignedMinus(coord.row, 1); row <= coord.row + 1; ++row){
for(unsigned int col = unsignedMinus(coord.col, 1); col <= coord.col + 1; ++col){
Coordinata neighbour = {row, col};
mat.append(neighbour);
};
};
return mat;
}
enum pixelFiltresEnum{
MORE,
LESS,
EQUAL,
APPROX,
NOT,
APPROX_NOT,
};
enum Actions{
YESNO_SEARCH,
FULL_SEARCH,
SUB,
};
typedef bool (*func)(PixelRGB256, PixelRGB256, int);
func pixelFiltres[] = {morePixel, lessPixel, equalPixel, approxPixel, notPixel, approxnotPixel};
/*
auto objectSearch(Matrix<PixelRGB256, 1, 8> pm, int cols, PixelRGB256 sp, int filter, int action, PixelRGB256 addit_arg={0, 0, 0}){
Coordinata searchcoord = {0, 0};
Matrix<PixelRGB256, 1, 8> outmatrixP;
Matrix<bool, 1, 8> outmatrixB;
for(int col = 0; col < cols; ++col){
for(int row = 0; row < 8; ++row){
if(pixelFiltres[filter](pm.index(searchcoord), sp)){
if(action == YESNO_SEARCH){return true;}
else if(action == FULL_SEARCH){
outmatrixB.append(pixelFiltres[filter](pm.index(searchcoord), sp));
}else if(action == SUB){outmatrixP.index(searchcoord) = addit_arg;};
if(searchcoord.row == 8-1){
++searchcoord.col;
searchcoord.row=0;
}else{++searchcoord.row;}
};
};
};
return false;
};
*/ //Пока закомментировано, плодит ошибки, но использования не предвидится
auto splitImage(Matrix<PixelRGB256, 1, 8> image, int threshold){
Matrix<bool, 1, 8> outmatr;
int objectcount = 0;
int checknb = 0;
for(Coordinata coord = {0, 0}; coord.row < 8 and coord.col < 1; inc(coord, 8)){
Matrix<Coordinata, 3, 3> the_neighbours = neighbours(coord);
for(Coordinata i = {0, 0}; i.col <= 2 and i.row <= 2; inc(i, 3)){
if(approxnotPixel(image.index(the_neighbours.index(coord)), image.index(the_neighbours.index(i)), threshold)){ //I compare a coordinate with its neighbor
continue;
}else if(outmatr.index(the_neighbours.index(i)) != 0){
outmatr.append(outmatr.index(the_neighbours.index(i)));
++checknb;
};
};
if(checknb == 0){
++objectcount;
};
};
return outmatr;
}
PixelRGB256 test1 = {255, 255, 255};
PixelRGB256 test2 = {255, 255, 254};
PixelRGB256 test3 = {255, 255, 253};
PixelRGB256 test4 = {255, 255, 252};
PixelRGB256 test5 = {255, 255, 251};
PixelRGB256 test6 = {255, 255, 250};
PixelRGB256 test7 = {255, 255, 249};
PixelRGB256 test8 = {255, 255, 248};
PixelRGB256 test1_1 = {255, 255, 240};
Matrix<PixelRGB256, 1, 8> matrix = {{test1, test2, test3, test4, test5, test6, test7, test8}};
PixelRGB256 testx1 = {255, 255, 255};
PixelRGB256 testx2 = {255, 255, 255};
PixelRGB256 testx3 = {255, 255, 255};
PixelRGB256 testx4 = {255, 255, 200};
PixelRGB256 testx5 = {255, 255, 200};
PixelRGB256 testx6 = {255, 255, 200};
PixelRGB256 testx7 = {255, 255, 255};
PixelRGB256 testx8 = {255, 255, 255};
Matrix<PixelRGB256, 1, 8> matrix2 = {{testx1, testx2, testx3, testx4, testx5, testx6, testx7, test8}};
int main(){
auto map = splitImage(matrix2, 10);
map.print();
}
У меня тупенькая мобильная ИДЕ, сначала вроде компилирует, после через секунду пустая строка - а под ней [Process completed - press Enter (signal 11)]. Я знаю только, что такое обозначение у меня - сегфолт. До этого стабильно возникал сегфолт. Ошибки я вроде исправил, но, видимо, неполностью. Программа теперь выдаёт то одно, то другое, то сегфолт. Причём на отладчике (codechef) всё выполняется. Искусственный интеллект ничем помочь не может. Что здесь не так?
Ответы (1 шт):
Я скомпилировал вашу программу и запустил под valgrind. Получил четырнадцать использований неинициализированных переменных. Первое такое:
==672949== Conditional jump or move depends on uninitialised value(s) ==672949== at 0x109AAE: Matrix<PixelRGB256, 1, 8>::index(Coordinata) (temp.cpp:56) ==672949== by 0x1095C6: splitImage(Matrix<PixelRGB256, 1, 8>, int) (temp.cpp:164) ==672949== by 0x10975E: main (temp.cpp:201)
Строка 56: if(coord.row >= rows or coord.col >= cols){
Ищите что из coord.row, rows, coord.col, cols вы не задаёте.
P.S. Не называйте IDE "тупенькой". Во-первых, чтобы отлаживать такие проблемы как ваша, IDE не нужна. Достаточно компилятора и valgrind. Во-вторых, не бывает тупого инструментария, бывает им не умеют пользоваться.
P.P.S. Должен сказать, вы молодец. Код скомпилировался относительно легко.