none
VS2012에서의 포인터 연산 문제 RRS feed

  • 질문

  • /* 메모리에 로드된 문서들을 가리키는 포인터 배열*/
    char *pDocs[150];
    char *pStr;
    
    ...
    
    for(int i=0; i<countFiles; i++)	/* 문서 개수만큼 반복 */
    {
    	/* 문서를 메모리에 로드하고, 포인터가 그 위치를 가리키도록 함 */
    	pDocs[i] = loadText( files[i], NORMAL );	
    }
    
    ...
    
    while( pDocs[i][0] )
    {
    	strBuffer[0] = '\0';
    	strcat(strBuffer, getWord(pDocs[i]));
    	removePunctuation(strBuffer);
    
    	strcat( chunkSet[ countChunks ], strBuffer );
    	if( ( (hashString( strBuffer ) % C) == 0 ) && getSizeofChunk( chunkSet[ countChunks ] ) > 1 )
    		countChunks++;
    	else
    		strcat( chunkSet[countChunks], " ");
    
    	pStr += strlen( strBuffer ) + 1; /* vs2012에서 문제 발생 */
    }

    프로그램 개요는 이렇습니다:

    1. files 배열에서 읽으려는 파일 이름을 가지고 와서 loadText() 함수 안에서 배열에 저장, 해당 배열에 대한 포인터를 리턴 -> pDocs[i] 에 포인터 저장

    char *loadText(char *filename, int option)
    {
    	char *str, *buffer;
    	ifstream inFile;
    	int fileSize;
    
    	inFile.open(filename);
    	if( inFile.fail() )	return NULL;
    
    	inFile.seekg(0, ios::end);
    	fileSize = (int)inFile.tellg();
    	inFile.seekg(0, ios::beg);
    	
    	buffer = new char [fileSize+2];
    	str = new char [fileSize+2];
    
    	memset(str, 0, fileSize+2);
    
    	while( !inFile.eof() )
    	{
    		//inFile.getline(buffer, fileSize+1);
    		buffer[0] = '\0';
    
    		inFile >> buffer;
    		removeSpecialChar(buffer);
    		strcat( str, buffer);
    
    		if( !inFile.eof() && option == NORMAL )
    			strcat( str, " ");
    	}
    	inFile.close();
    
    	return str;
    }

    2. pStr 포인터가 pDocs[i] 를 가리키게 한 다음, 문자열 데이터를 처리하고, pStr 포인터를 다음 단어를 가리키게 하는 연산을 수행하는 루프

    // strBuffer: pStr이 가리키는 문자 배열의 첫번째 단어를 저장
    pStr += strlen( strBuffer ) + 1; /* 단어와 단어 사이의 공백을 처리하기 위해 1을 더함 */

    포인터에서 정수를 더하는 연산에서 문제가 발생합니다. VS2010에서는 문제가 없었는데 VS2012에서만 문제가 발생하네요.

    안전하지 못한 방법으로 코딩을 해서 그런건지 궁금합니다.

    2012년 7월 26일 목요일 오전 6:45

답변

  • 답변해주신 모든 분들께 감사드립니다.

    제가 겪는 문제를 확실히 기술했어야 했는데 그러지 못한 것 같아 죄송합니다.

    컴파일/빌드 과정에서의 에러가 아니라 단순히 디버그 도중에 스트링 데이터가 제대로 출력되지 않는 문제였는데.. 코드를 여기 저기 적다보니 정작 중요한 사실을 빼먹은 것 같네요;;

    그래도 손수 코드까지 수정해 주시고.. 너무 감사합니다!

    2012년 7월 30일 월요일 오전 3:36

모든 응답

  • 안녕하십니까? 큰곰아저씨 님,
    Microsoft TechNet 의Forum 사이트를 방문해 주셔서 감사합니다.

    질문을 깔끔하게 올려주셔서 감사합니다.  =)

    포인터에서 정수를 더하는 연산에서 어떤 문제가 발생하는지 응답부탁드립니다.

    감사합니다.

    2012년 7월 26일 목요일 오후 1:48
    중재자
  • 오류가 나는 위치에 pStr의 사용법은 문제가 없는듯합니다. 하지만, pStr 에 pDocs[i] 값을 넣는 부분이나 다음 단어쪽으로
    이동하는 부분까지 코드가 있었다면 더 좋았을텐데, 지금 코드만으로는 버그를 논하기에 자료가 부족해 보입니다.

     

    2010 에서 잘되던것이 2012에서 안되는건 좀 특이한 현상이네요. 제대로된 코드가 있다면 디버깅 돌려보면 어느정도
    체크가 될듯도한데, 현재로써는 답변을 드릴만한게 없습니다.

    아. 마지막으로 문제가 발생한다는 뜻이 어떤 종류의 에러가 발생하고 디버깅 모드로 실행했다면 어떤 종류의 익셉션이
    출력되는지도 남겨주시면 추측하는데 도움이 될듯합니다.

    2012년 7월 26일 목요일 오후 4:00
    중재자
  • 안녕하세요. 엄준일 입니다.
    제가 보기에도 포인터 연산의 문제라고 말씀하시는 코드 상의 문제는 없어 보입니다.

    다만, 코드 중에 좀 부족한 부분이 있습니다.
    pStr 이 문서의 특정 Point 를 가르키는 포인터인데, pStr 포인터에 pDocs 를 참조하는 코드가 보이지 않네요.

    아마 pDocs 가 로드된 이후에 다음과 같은 코드로 pDocs 를 올바로 참조하고 있는지 확인해 보시기 바랍니다.

    char*& pStr = const_cast<char*&>(pDoc[0]);

    감사합니다


    엄준일 (Junil, Um) Microsoft Visual Studio ALM MVP (Team System) Personal Blog : http://blog.powerumc.kr Visual Studio Korea Team Blog : http://vsts2010.net


    • 편집됨 엄준일 2012년 7월 26일 목요일 오후 4:31
    2012년 7월 26일 목요일 오후 4:15
  • 이제서야 답변들을 확인했습니다;; 죄송합니다.

    pStr 포인터는 작업이 완료된 다음 가리키고 있는 문서의 다음 단어를 가리키게 됩니다

    예시: 는 학교에 버스를 타고 간다(수행 전) -> 나는 교에 버스를 타고 간다(수행 후)
    (밑줄 : 포인터 위치)


    문제는 디버그 모드에서 pStr이 가리키는 문서의 내용이 제대로 출력되지 않는다는 건데요.

    *pStr: 초기 상태
    + pStr 0x004771b0 "/*문서 내용..*/ char *

    *pStr: movePointer() 호출 후
    + pStr 0x004771b7  <문자열에 잘못된 문자가 있습니다.> char *

    아래는 포인터를 이동시키는 movePointer() 함수입니다.

    char *movePointer(char *pStr)
    {
    	int length = strlen(pStr);
    
    	while( pStr && *pStr != ' ' )
    	{
    		pStr++;
    
    		if( ( length = strlen(pStr) ) == 0 )
    			break;
    	}
    
    	if( length != 0 )
    	{
    		while( pStr )
    		{
    			if( *(pStr+1) == ' ')
    				pStr++;
    			else	break;
    		}
    		return ++pStr;
    	}
    	else
    		return NULL;
    }

    디버그 모드에서 movePointer() 함수의 루프를 한 번씩 돌려보면,

    는 학교에 버스를 타고 간다 : 초기상태, 잘 표시 됨

    학교에 버스를 타고 간다 : 1회 수행, <문자열에 잘못된 문자가 있습니다>

    나는 학교에 버스를 타고 간다 : 2회 수행('나는' 뒤의 공백문자를 가리킴), 잘 표시 됨

    나는 교에 버스를 타고 간다 : 루프 마침, ++pStr 연산으로 포인터 이동, <문자열에 잘못된 문자가 있습니다>

    이렇게 출력되는 문제가 발생합니다. 2010에서는 잘 수행되던 코드들이 2012에 와서 이러니 난감합니다. 이 문제가 일관성 있게 발생하는 것도 아니라서, 무시하고 계속 진행하다가 보면 또 pStr이 제대로 된 문서 내용을 출력할 때도 있고 해서.. 어디가 문제인지 잘 모르겠습니다.

    2012년 7월 29일 일요일 오전 4:54
  • 반복문에서 pStr 이라고 사용한것은 의미상 *pStr 이라고 사용했어야 하는게 맞을것 같습니다.
    지금 사용된 코드에서 pStr 이 NULL 이였다면 strlen 에서 오류가 발생할 것이고 pStr++ 로 pStr 이 NULL이
    되려면 해당 문자열이 INT_MAX 를 넘어가야 할텐데, 이것은 사실상 불가능합니다.

     

    그리고 첫번째 반목문에서 strlen 을 사용한것도 의미가 없습니다. 아마도 while 문에서 pStr 을 *pStr 로
    사용했다면 필요가 없었을겁니다. 위 코드를 같은 의미를 가지도록 수정해보면 아래와 같습니다.

     

    char *movePointer(char *pStr)
    {
        while(*pStr && *pStr != ' ') pStr++;

        if(strlen(pStr) > 0){
            while(*pStr){
                if(*(pStr+1) == ' ') pStr++;
                else break;
            }
            return ++pStr;
        }

        return NULL;
    }

    2012년 7월 29일 일요일 오후 4:35
    중재자
  • 답변해주신 모든 분들께 감사드립니다.

    제가 겪는 문제를 확실히 기술했어야 했는데 그러지 못한 것 같아 죄송합니다.

    컴파일/빌드 과정에서의 에러가 아니라 단순히 디버그 도중에 스트링 데이터가 제대로 출력되지 않는 문제였는데.. 코드를 여기 저기 적다보니 정작 중요한 사실을 빼먹은 것 같네요;;

    그래도 손수 코드까지 수정해 주시고.. 너무 감사합니다!

    2012년 7월 30일 월요일 오전 3:36