2014-07-15 9 views
-1

C를 사용하여 atmega8535를 프로그래밍하고 있습니다. ALFAT OEM 모듈을 사용하여 플래시 디스크에 데이터를 저장하려고합니다. 하지만, 저장하려는 데이터가 중간 프로그램의 다른 변수로 바뀌기 때문에 문제가 발생합니다 (데이터 저장은 성공하지만 데이터가 잘못됨). malloc 후에 발생합니다. 변수 데이터를 이미 malloc했다. 내 프로그램을 디버깅하는 데 하이퍼 터미널을 사용하고 있습니다.char *의 malloc 또한 다른 char * 변수를 변경합니다.

이것은 내 코드입니다. 나는 그걸 보여줄뿐입니다.

// Declare your global variables here 
char* reply = NULL; 
char* directory = NULL; 
char* fileName = NULL; 
char* getFileName = NULL; 

void writeCommand(char* command){ //to give command to ALFAT 
    //not related 
} 

void readCommand(){ //to request reply from ALFAT 
    //related (because contains malloc and also change my variable) but I give another example 
} 

void get_ErrorCode(char errorCode[4]){ //to get errorCode from ALFAT's reply 
    //not related 
} 

void get_Version(){ //to know ALFAT's version 
    //not related 
} 

void mountUSB0(){ //to mount USB port 0 
    //not related 
} 

void mountUSB1(){ //to mount USB port 1 
    //not related 
} 

void get_fileName(){ //to get fileName from ALFAT's reply after N command 
    //not related 
} 

int check_File(char port[1]){ //to check whether file already exists or not 
    //related (because contains malloc and also change my variable) but I give another example 
} 

void separate_Directory(char* fullDir, char* data){ //to separate directory and fileName from fullDirectory "fullDir" 
    int i,j; 
    int numSlash = 0;    //numberOfSlash 
    int curNumSlash = 0;   //currentNumberOfSlash 

    //CHECK THE DATA BEFORE MALLOC 
    printf("1st GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory); 

    //count backslash '\'=0x5C 
    for (i=0;i<strlen(fullDir);i++){ 
     if(fullDir[i]== 0x5C) numSlash++; 
    } 

    //count number of char for directory 
    i=0; 
    curNumSlash = 0; 
    while (curNumSlash != numSlash){ 
     if(fullDir[i]== 0x5C) curNumSlash++; 
     i++; 
    } 

    //i = number of char for directory 
    //number of char for filename = strlen(fullDir)-total char directory 
    do{ 
     directory = (char *) malloc (i+1); 
    }while(directory==NULL); 
    do{ 
     fileName = (char *) malloc (strlen(fullDir)-i+1); 
    }while(fileName==NULL); 

    //CHECK THE DATA AFTER MALLOC (ALREADY CHANGED) 
    printf("2nd GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory); 

    //save into directory until last backslash 
    i=0; 
    curNumSlash = 0; 
    while (curNumSlash != numSlash){ 
     if(fullDir[i]== 0x5C) curNumSlash++; 
     directory[i] = fullDir[i]; 
     i++; 
    } 
    directory[i] = '\0'; 

    //remaining fullDir into fileName 
    j=0; 
    while (i < strlen(fullDir)){ 
     fileName[j] = fullDir[i]; 
     i++; 
     j++;  
    } 
    fileName[j] = '\0'; 

    //CHECK THE DATA AGAIN (CHANGED INTO directory) 
    printf("3rd GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory); 
    printf("separate directory = %s, fileName = %s, fullDir = %s\n",directory,fileName,fullDir); 
} 


void writeData (char* data, char* fullDir, char port[1], char statFileHandler[16]){ 
//I omit that not related 

    printf("1)!!!!!!!!!!!!!!!!DATA = %s, ADDRESS DATA = %x, DIRECTORY = %s, ADDRESS DIRECTORY = %x\n",data,*data,directory,*directory); 
    separate_Directory(fullDir,data); 
    printf("2)!!!!!!!!!!!!!!!!DATA = %s, ADDRESS DATA = %x, DIRECTORY = %s, ADDRESS DIRECTORY = %x\n",data,*data,directory,*directory); 

//omitted 
} 

void main(){ 
    char* data; 
    char* fullDir = NULL; 
    char port[1]=""; 
    char statFileHandler[16]; 

    //omitted 

    while(1){ 
     //omitted (also omit the mounting) 


     do{ 
      data = (char *) malloc (strlen("meong")+1); //+1 utk \0 
     }while(data==NULL); 
     strcpy(data,"meong"); 
     data[strlen("meong")] = '\0'; 

     fullDir = (char *) malloc (strlen("\\f1\\nyan.txt")+1); 
     strcpy(fullDir,"\\f1\\nyan.txt"); 
     fullDir[strlen("\\f1\\nyan.txt")] = '\0'; 
     for(i=0;i<strlen("\\f1\\nyan.txt");i++){ 
      fullDir[i] = toupper(fullDir[i]); 
     } 

     //omit some printf for debugging 
     printf("fullDir di main= %s\n",fullDir); 

     printf("data di main = %s\n",data); 
     printf("address data di main = %x\n",*data); 
     writeData (data, fullDir, port, statFileHandler); 

     break;       
     } 

     while(1){} 

     } 
    } 
} 

GUNYUH 부분을 확인하십시오. 하이퍼 터미널의 출력 :

1st GUNYUH data = meong, address data = 196, directory = , address directory = 0 
2nd GUNYUH data = , addressdata = 196, directory = , address directory = 196 
3rd GUNYUH data = \F1\, address data = 196, directory = \F1\, address directory = 196 

내 데이터는 "meong"입니다.

1 GUNYUH의 malloc 전에 데이터는 여전히 "meong"디렉토리를 정의 후

2 GUNYUH malloc을 한 후, 데이터가 이미 데이터도 변경,

3 GUNYUH을 변경했습니다. (주소가 같기 때문에 같은 주소를 가리킬 수도 있습니다.)

왜 변경 되었습니까?

메모리 부족 문제입니까? 그러나 힙 메모리가 충분하지 않으면 malloc이 NULL을 반환하여 루프에서 절대 나가지 않습니다. 이전에 힙 메모리가 부족하다는 것을 이미 경험했고 루프에서 빠져 나올 수 없었습니다.

나는 이와 같이 중복 된 경험이있다. 하지만 malloc을 사용하지 않았기 때문입니다. (하지만 주소를 확인하지 않고 정적 배열로 이동했지만 메모리가 충분하지 않아 동적으로 되돌아 가서 malloc이 필요하다는 것을 알았습니다)

일부 도움주세요.

+1

주소 (포인터 값)를 인쇄 할 때 * 데이터가 아닌 데이터 (문자열의 첫 번째 문자)를 인쇄하려고합니다. –

+0

수정 해 주셔서 감사합니다. 이미 질문을 편집합니다. 그러나 malloc이 데이터와 동일한 주소를 가리키는 이유는 무엇입니까? – Kalkaneus

+0

REAL 코드를 알려주십시오. – zoska

답변

1

이것은 답변이 아니지만 설명을하기에는 너무 큽니다. 당신이 %s을 위해 널 포인터를 전달하여 정의되지 않은 동작이 발생할

  • 다른 printf 행 사에 :

    는 다음과 같은 버그가 있습니다. (변수 directory). 정의되지 않은 동작이 시작되면 모든 베팅이 해제됩니다.

  • %x으로 포인터를 인쇄하면 정의되지 않은 동작이 발생합니다. 포인터를 인쇄하려면 %p을 사용하고 포인터를 (void *)으로 변환하십시오.
  • 당신은 i이 선언되지 않은 것입니다,
  • Don't cast mallocprintf는, 캐스트가 라인 for(i=0;i<strlen("\\f1\\nyan.txt");i++){에 버그
  • 을 나타내는 오류 메시지가 숨어있을 수 있습니다에 대한 *THING 대신 3 개 개의 다른 장소에서 THING 않습니다.
  • stdio.h, stdlib.hstring.hctype.h을 포함하지 못했습니다.
  • 코드에는 {보다 두 개의 }이 더 있습니다.
  • fullDir = (char *) malloc ...이 (가)있는 줄 뒤에 malloc이 실패했는지 확인하지 않습니다.

이 코드는 컴파일해서는 안됩니다. 이것은 당신이 실제 코드를 게시하지 않는다고 믿게합니다. 정확히 코드를 게시하는 것이 중요합니다.

create a minimal program이 필요하며, 해당 프로그램이 여전히 문제를 보여 주는지 테스트하고, 해당 프로그램의 코드를 변경없이 게시하십시오.

"실제 코드"에 있지만 사용자가 게시 한 코드에는 문제가있을 수 있기 때문입니다. 문제가 어디인지 모르기 때문에 문제의 원인이되는 부분을 포함 시켰는지 확신 할 수 없습니다.

실제로 위에 나열된 모든 버그를 수정하고 main() 끝에 무한 루프를 제거하면 코드가 컴파일되어 성공적으로 실행됩니다. 그것은 나열된 포인트 중 하나가 문제이거나, 게시하지 않은 코드에 문제가 있음을 나타냅니다.

+0

내 코드를 게시하고 있습니다. 그러나 나는 관련이 없다고 생각하지 않는다. 의도하지 않게 {}의 일부가 누락되었을 수 있습니다. 또한 생략됩니다. 어쩌면 변수가 생략되었을 수도 있습니다. 나는 이미 내 코드를 편집하여 * 물건이 아니라 물건입니다. 또한 이미 내 결과를 편집합니다. 모든 프로그램은 약 800 + 라인입니다. 나는 그것을 여기에 게시하는 것을 너무 많이 생각한다. 그러나 문제가 거기에 있지 않다는 것이 맞습니다. 그냥 최근에 (마침내), 나는 free()하는 모든 변수를 NULL로 만들려고했다. 그리고 제 코드가 작동합니다. 대답 해줘서 고마워. = D – Kalkaneus

+0

REAL 코드를 게시해야합니다. 그렇지 않으면 도움을 줄 수 없습니다. 문제와 관련이없는 것 같아도 문제의 원인 일 수 있습니다. – zoska

+0

죄송합니다. 처음에는 REAL 코드가 ALL 코드와 다르다고 생각했습니다. 그것은 모든 코드가 진짜 코드 인 것 같습니다. – Kalkaneus