2013-07-25 4 views
1

저는 C++로 프로그래밍하기 시작합니다. 파일에서 16 진수 색상을 읽고, 프로그램에서 식별 된 색상 배열과 수학적으로 비교하여 가장 가까운 색상을 결정한 다음 원본 색상과 가장 가까운 색상을 파일에 씁니다. 어떤 이유로 약 62,000 줄 정도를 작성한 후에 프로그램은 스택 덤프를 사용합니다. 내가 읽고있는 파일에는 약 1,600 만 가지의 색상이 있습니다. 나는이 문제를 해결하기 위해 누군가 내 코드로 올바른 방향으로 나를 가리킬 수 있기를 희망했다.루프가 스택 덤프를 일으키고 프로그램이 C++에서 충돌하는 동안

아래 코드는 빨간색, 녹색, 파란색 또는 pantonehexcode 배열을 붙여 넣지 않았습니다. 그러나 숫자와 16 진수 문자열 값이 각각 있다고 가정 할 수 있습니다. 당신의 rgb2lab 기능에

string line; 
string hexcolor, r_hex, g_hex, b_hex; 

const char delim[] = " ;"; 
float *cie1 = new float[3]; 
float *cie2 = new float[3]; 

float r ; 
float g ; 
float b ; 
float currentClosestVal = 1000000; 
float challengeClosestVal; 
int currentClosestIndex; 

    ifstream file ("hexcolormaplist.txt"); 
if (file.fail()) 
     {cout << "Error opening infile file"; return 0;} 
ofstream ofile("tpxmap.txt"); 
if (ofile.fail()) 
     {cout << "Error opening ofile file"; return 0;} 

bool newline = true; 
//Comparing colors variables 
int i, k; 
double Kl, K1, K2, Sl, SC, SH, dL, dA, dB, dC, dH, c1, c2; 

getline (file,line); 
char * cline = new char [line.length()+1]; 



while(newline == true){ 

    currentClosestVal = 1000000; 
    std::strcpy (cline ,line.c_str()); 
    hexcolor = strtok(cline, delim); 
    r_hex = strtok(NULL, delim); 
    g_hex = strtok(NULL, delim); 
    b_hex = strtok(NULL, delim); 


    r = (float)atof(r_hex.c_str()); 
    g = (float)atof(g_hex.c_str()); 
    b = (float)atof(b_hex.c_str()); 

    cie1 = rgb2lab (r, g, b); 



    for (i = 0; i < 2100; i++) 
    { 
     cie2 = rgb2lab (red[i], green[i], blue[i]); 
     //challengeClosestVal = pow(cie1[0] - cie2[0], 2.0) + pow(cie1[1] - cie2[1], 2.0) + pow(cie1[2] - cie2[2], 2.0); 
     dL = cie1[0] - cie2[0]; 
     dA = cie1[1] - cie2[1]; 
     dB = cie1[2] - cie2[2]; 
     c1 = sqrt(cie1[1] + cie1[2]); 
     c2 = sqrt(cie2[1] + cie2[2]); 
     dC = c1 - c2; 
     dH = sqrt(pow(dA, 2) + pow(dB,2) - pow(dC,2)); 
     Kl = 2; 
     K1 = .048; 
     K2 = .014; 
     Sl = 1; 
     SC = 1 + K1*c1; 
     SH = 1 + K2*c1; 

     challengeClosestVal = sqrt(pow(dL/(Kl*Sl), 2) + pow(dC/(Kl*SC),2) + pow(dH/(Kl*SH), 2)); 


     if(challengeClosestVal < currentClosestVal){ 
      currentClosestIndex = i; 
      currentClosestVal = challengeClosestVal; 
     } 
    } 

    ofile << hexcolor <<"; " << pantoneHexCodes[currentClosestIndex] <<";"<<endl; // prints The pantone color comparator 
    line = ""; 
    newline = getline (file,line); 

}//end of while loop 

//close files 
file.close(); 
ofile.close(); 
return 0; 
} 

float *rgb2lab (float r, float g, float b){ 

    float var_r, var_g, var_b; 
    double X, Y, Z, var_X, var_Y, var_Z; 
    float ref_X = 95.047; //Observer= 2°, Illuminant= D65 
    float ref_Y = 100.000; 
    float ref_Z = 108.883; 
    double cieL, cieA, cieB; 
    float *cie = new float[3]; 



    //Convert RGB to XYZ 
    //First set RGB values between 0-1 
    var_r = r/255; 
    var_g = g/255; 
    var_b = b/255; 

    if (var_r > 0.04045) 
      var_r = pow((var_r + 0.055)/1.055 , 2.4); 
    else 
      var_r = var_r/12.92; 

    if (var_g > 0.04045) 
      var_g = pow((var_g + 0.055)/1.055 , 2.4); 
    else 
      var_g = var_g/12.92; 
    if (var_b > 0.04045) 
      var_b = pow((var_b + 0.055)/1.055 , 2.4); 
    else 
      var_b = var_b/12.92; 

    var_r = var_r * 100; 
    var_g = var_g * 100; 
    var_b = var_b * 100; 

    //Convert RGB to XYZ 
    //Observer. = 2°, illuminant = D65 
    X = var_r * 0.4124 + var_g * 0.3576 + var_b * 0.1805; 
    Y = var_r * 0.2126 + var_g * 0.7152 + var_b * 0.0722; 
    Z = var_r * 0.0193 + var_g * 0.1192 + var_b * 0.9505; 

    //cout << "X: "<<X <<" Y: " <<Y <<" Z: "<<Z << endl; 


    // Convert XYZ to CIELab 
    var_X = X/ref_X;   //ref_X = 95.047 Observer= 2°, Illuminant= D65 
    var_Y = Y/ref_Y;   //ref_Y = 100.000 
    var_Z = Z/ref_Z;   //ref_Z = 108.883 
    //cout << "var_X: "<<var_X <<" var_Y: " <<var_Y <<" var_Z: "<<var_Z << endl; 

    if (var_X > 0.008856) { 
      var_X = pow(var_X, .3333333); } 
    else 
      var_X = (7.787 * var_X) + (16/116); 
    if (var_Y > 0.008856){ 
      var_Y = pow(var_Y, .3333333); } 
    else 
      var_Y = (7.787 * var_Y) + (16/116); 
    if (var_Z > 0.008856){ 
      var_Z = pow(var_Z, .3333333); } 
    else 
      var_Z = (7.787 * var_Z) + (16/116); 


    cieL = (116 * var_Y) - 16; 
    cieA = 500 * (var_X - var_Y); 
    cieB = 200 * (var_Y - var_Z); 

    //cout << "L: "<<cie[0] <<" a: " <<cie[1] <<" b: "<<cie[2] << endl; 
    cie[0] = cieL; 
    cie[1] = cieA; 
    cie[2] = cieB; 
    //cout << "L: "<<cie[0] <<" a: " <<cie[1] <<" b: "<<cie[2] << endl; 
    return cie; 

} 
+1

코드 들여 쓰기 :

또 다른 해결책은 cie 값에 대한 구조체를 만들고 구조체를 반환하는 것입니다. 그것을 사용하십시오. – Borgleader

+0

크래시 덤프를 읽는 방법과 디버깅 방법을 알아야합니다. – marcinj

+0

디버그 기호로 컴파일 했습니까? 그렇다면 핵심 파일이 있습니까? 디버거로 코어 파일을 검사 해 보셨습니까? 충돌을 반복 할 수 있습니까? 매번 같은 반복에서 발생합니까? 리눅스를 사용하고 있다면, 컴파일러의'-g' 플래그는 디버그 기호를 추가하고 코어를 검사 할 것입니다. - gdb <실행 파일>' – Macattack

답변

1

당신은 new float[3]을 만듭니다. 이것은이 함수를 호출 할 때마다 발생합니다. 코드를 살펴보면 어디서나 delete을 호출하여 메모리가 해제 된 것을 볼 수 없습니다.

모든 newdelete과 쌍을 이루는 것이 좋습니다. 또한 이 무언가가 new으로 만들어지면 프로그램의 모든 실행 경로에서 호출되는 것이 더 중요합니다.

코드에서 발생하는 현상은 파일에 기록 된 모든 행에 대해 rgb2lab 함수가 2100 번 호출된다는 것입니다. 파일에 기록되는 약 62000 줄 이후에 프로그램이 엉망이된다는 말을 듣고 있습니다. 이 경우 rgb2lab 함수는 130,200,000 번 호출되고 매번 메모리가 누수됩니다.

편집 :

당신은 new을 호출하는 장소의 몇 가지를 가지고 당신이 delete을해야하지만, 가장 큰 범죄자가 계속해서 또 다시 rgb2lab 함수를 호출하는 2100 반복 for 루프입니다. 함수가 반환하는 동적으로 할당 된 배열을 사용하고 있으므로 사용이 끝나면 메모리를 해제하십시오.

for (i = 0; i < 2100; i++) 
{ 
    cie2 = rgb2lab (red[i], green[i], blue[i]); 
    //challengeClosestVal = pow(cie1[0] - cie2[0], 2.0) + pow(cie1[1] - cie2[1], 2.0) + pow(cie1[2] - cie2[2], 2.0); 
    dL = cie1[0] - cie2[0]; 
    dA = cie1[1] - cie2[1]; 
    dB = cie1[2] - cie2[2]; 
    c1 = sqrt(cie1[1] + cie1[2]); 
    c2 = sqrt(cie2[1] + cie2[2]); 
    dC = c1 - c2; 
    dH = sqrt(pow(dA, 2) + pow(dB,2) - pow(dC,2)); 
    Kl = 2; 
    K1 = .048; 
    K2 = .014; 
    Sl = 1; 
    SC = 1 + K1*c1; 
    SH = 1 + K2*c1; 

    challengeClosestVal = sqrt(pow(dL/(Kl*Sl), 2) + pow(dC/(Kl*SC),2) + pow(dH/(Kl*SH), 2)); 


    if(challengeClosestVal < currentClosestVal){ 
     currentClosestIndex = i; 
     currentClosestVal = challengeClosestVal; 
    } 
} 
delete [] cie2; // <-- Free up the memory here! 
+0

감사합니다. 내가 그것을 삭제하기 전에 내가 만든 배열을 반환하려고하는 경우 어디에 내가 삭제하겠습니까? – user1370238

+0

'new'와'delete'를 사용하지 말고 값이나 참조로 전달하십시오. –

+1

반환 된 배열을 사용한 후에'delete []'를 배치해야합니다. 배열을 할당하고 삭제하면 프로그램 속도가 느려집니다. –

1

(당신은 Java 또는 C# 배경에서 오는 제외)는 new 연산자를 사용하는 이유는 표시되지 않습니다. new 연산자를 사용하지 않고도 결과를 전달할 수 있습니다. 예를 들어

:

void rbg_to_lab (float r, float g, float b, 
       float& cie[3]) 
{ 
// ... 
} 

어떤 new 메모리 오브젝트를 할당 직접 호출자의 변수를 수정할 수있는 기준으로서 cie 어레이를 통과시킴으로써 (그리고 어느 delete 메모리를 갖는 없음.).

struct Cie_Values 
{ 
    float cie_1; 
    float cie_2; 
    float cie_3; 
}; 

Cie_Values rgb_to_lab(float r, float g, float b) 
{ 
    Cie_values cie; 
    // Perform conversion 
    return cie; 
} 
+0

감사합니다. Thomas, 감사합니다. – user1370238