2013-08-16 2 views
-1

매우 이상한 문제가 있습니다. 헤더 파일클래스 객체를 사용하여 클래스의 구조에 값을 할당합니다.

namespace test 
{ 
class LoadConfigData 
{ 

    struct control_params 
    { 
     char    active[]; 
     char    suspended[]; 
     char    erased[];   
    }*ctrl_params; 
bool loadConfig(); 
}; 
}; 

하여 Main.cpp

using namespace std; 
using namespace test; 
namespace test 
{ 
extern LoadConfigData   *loadConfigDataobj; 
LoadConfigData *loadConfigDataobj = new LoadConfigData; 
}; 
int main() 
{ 
loadConfigDataobj->loadConfig(); 
cout <<loadConfigDataobj->ctrl_params->active_status_code_v<<endl; 
cout <<loadConfigDataobj->ctrl_params->suspended_status_code_v<<endl; 
cout <<loadConfigDataobj->ctrl_params->erase_status_code_v<<endl; 
return 0; 
} 

bool LoadConfigData::loadConfig() 
{ 
std::string a = "AC"; 
std::string b = "SP"; 
std::string c = "ER"; 
LoadConfigData::ctrl_params = new LoadConfigData::control_params; 
sprintf(loadConfigDataobj->ctrl_params->active,"%s",a.c_str()); 
sprintf(loadConfigDataobj->ctrl_params->suspended,"%s",b.c_str()); 
sprintf(loadConfigDataobj->ctrl_params->erased,"%s",c.c_str()); 
return true; 
} 

출력 : 여기 내 코드는 각 구조체 멤버의 마지막 복사 된 문자열을 인쇄하는 것을 의미

ER 
ER 
ER 

. 내 코드가 잘못되었습니다.

답변

1

문제는 당신이 문자 배열을 크기를 포기하지 않는다는 것입니다 :이 컴파일 오히려 놀랐어요

struct control_params 
{ 
    char    active[]; 
    char    suspended[]; 
    char    erased[];   
}*ctrl_params; 

을; 내 이해는 unsized 배열이 불완전한 형식이므로 비 정적 클래스 멤버가 될 수 없습니다. 그러나, 적어도 내 컴파일러는 (아마도 당신의 것) 메모리의 같은 위치에있는 모든 크기가 0 인 배열로 취급합니다. 따라서 하나에 쓸 때마다 다른 사람에게 쓴 것을 덮어 씁니다. (물론, 배열 경계 바깥에 쓰므로 동작은 정의되지 않습니다.)

가장 간단한 해결책은 std::string을 사용하여 문자열을 나타내는 것입니다. 그러면 자동으로 크기가 관리되므로 sprintf (또는 약간 더 현명하게는 strncpy)으로 엉망이되어 버퍼 오버런이 발생하지 않도록하기 위해 간단히 active = a을 작성할 수 있습니다.

+0

예. 맞습니다. 크기가 지정되지 않은 배열의 경우 문제였습니다. 크기를 정의하면 내 문제가 해결되었습니다. 감사합니다 :) – sajal

+1

@sajal : 당신이하고있는 것을 정확히 알고 있습니까? 끈이 항상 충분히 커야 확실합니까? 왜'std :: string'을 사용하지 않을까요? 이들이 실제로 구성 데이터 인 경우 입력 길이에 대한 제어가 필요하지 않으며 크래커가 환영 할 안전 문제가 있습니다. 문자열 기능 취약점에 대해 얼마나 알고 있습니까? http://en.wikipedia.org/wiki/Software_vulnerabilities에 대해 자세히 읽어보십시오. 특히 버퍼 오버플로 및 형식 문자열 공격에 대해서는 (독점적 인 것은 아니지만) 특히 그렇습니다. 나는 이것이 생산 코드가 아니고 배우기를 진심으로 희망한다. –

+0

@phresnel : 고맙습니다. 여기서 언급 한 코드는 내가 사용하고있는 코드와 다릅니다. 나는 char 배열의 형태로 데이터를 반환하는 특정 라이브러리를 사용해야하는 데이터베이스에서 데이터를 가져오고 control_params에 저장합니다. 문자열 크기를 알고 있으므로 지금 작동합니다. 하지만 문자열 크기가 나중에 변경되면 코드를 변경하는 것 외에 다른 옵션이 없습니다. – sajal

1

문제는 sprintf을 사용하는 것입니다. sprintf이 메모리를 할당하지 않을 경우 active, suspendederased이 이상하고 정의되지 않은 주소를 가리키고 있습니다. 정의되지 않은 동작을 호출하고 있습니다.

일반적으로 필요한 세부 정보를 모두 추가하지 않고 std::string을 사용하면 연산자 오버로드가 발생합니다. 간단한 구문 분석을 위해 스트림을 사용하십시오. 지금은 C 문자열 기능을 완전히 피하고 대신 C++ 만 사용하십시오.

관련 문제