2014-10-18 4 views
3

나는 C에서 프로젝트를 진행하고 있으며이는C 배열을 덮어 쓰거나 삭제하고 있습니까? 매우 혼란

파일에 단어의 발생 수를 유지 나의 배열을 덮어 쓰기 및 1,970,802,352 같은 이상한 숫자를 쓰는 것 같다 하나 개의 기능을 제외하고 큰 노력하고 있습니다 내 헤더 파일 :

#ifndef LIST_H 
#define LIST_H 
struct Node_{ 
     char* word; 
     //array holding names of files word occurs in 
     char **filesIn; 
     int numFilesIn; 
     //array holding count of how many times word occured in file 
     int* occursIn; 
     struct Node_ *next; 
     int isHead; 
}; 

typedef struct Node_ Node; 

int insert(char *wordToAdd, char *File); 

int addOccur(Node *addedTo, char *File); 

Node *createNode(char *wordToAdd, char *File); 

void destroyNodes(); 

#endif 

하고이 배열 덮어 쓰기를 유지하는 기능입니다 :

Node *head; 
int insert(char *wordToAdd, char *File){ 
     if(head == NULL){ 
       Node *new; 
       new = createNode(wordToAdd, File); 
       new->isHead = 1; 
       head = new; 
       return 0; 
     } 
     else{ 
       Node *trace; 
       trace = head; 
       char *traceWord; 
       int wordSize; 
       wordSize = strlen(trace->word); 
       traceWord = (char*) malloc(wordSize + 1); 
       strcpy(traceWord, trace->word); 
       int a =strcmp(wordToAdd, traceWord); 
       free(traceWord); 
       if(a == 0){ 
         int b = addOccur(trace, File); 
         //printf("addOccur returned %d\n", b); 
         return 0; 
       } 
       if(a < 0){ 
         Node *Insert = createNode(wordToAdd, File); 
         trace->isHead = 0; 
         Insert->isHead = 1; 
         Insert->next = trace; 
         head = Insert; 
         return 0; 
       } 
       else{ 


         Node *backTrace; 
         backTrace = head; 

         while(trace->next != NULL){ 
           trace = trace->next; 
           traceWord = trace->word; 
           a = strcmp(wordToAdd, traceWord); 
           if(a < 0){ 
             Node* Insert = createNode(wordToAdd, File); 
             Insert->next = trace; 
             backTrace->next = Insert; 
             return 0; 
           } 
           if(a == 0){ 
             addOccur(trace, File); 
             //free(wordToAdd); 
             return 0; 
           } 
           if(a > 0){ 
             backTrace = trace; 
             continue; 
           } 
         } 
         Node *Insert = createNode(wordToAdd, File); 
         trace->next = Insert; 
         return 0; 
       } 
     } 
     return 1; 
} 

다른 기능은 다음과 같습니다

gdb를 갈 때 515,
Node* createNode(char *wordToAdd, char *File){ 
     Node *new; 
     new = (Node*)malloc(sizeof(Node)); 
     memset(new, 0, sizeof(Node)); 
     new->word = wordToAdd; 
     char **newArray; 
     newArray = (char**)malloc(sizeof(char*)); 
     newArray[0] = File; 
     new->filesIn = newArray; 
     int a[1]; 
     a[0] = 1; 
     new->occursIn = a; 
     //new->occursIn[0] = 1; 
     new->numFilesIn = 1; 
     return new; 
} 

int addOccur(Node *addedTo, char *File){ 

     char **fileList = addedTo->filesIn; 
     char *fileCheck; 
     int i = 0; 
     int fileNums = addedTo->numFilesIn; 
     for(i = 0; i < fileNums; i++){ 
       fileCheck = fileList[i]; 
       if(strcmp(fileCheck, File) == 0){ 
         int *add1; 
         add1 = addedTo->occursIn; 
         int j = add1[i]; 
         j++; 
         add1[i] = j; 
         return 0; 
       } 
     } 

     int numberOfFilesIn; 
     numberOfFilesIn = addedTo->numFilesIn; 
     char **newList = (char**)malloc(sizeof(char*) * numberOfFilesIn + sizeof(char*)); 
     i = 0; 
     char *dest; 
     char *src; 
for(i = 0; i < numberOfFilesIn; i++){ 
       src = fileList[i]; 
       int len; 
       len = strlen(src); 
       dest = (char*)malloc(sizeof(char) * (len + 1)); 
       strcpy(dest, src); 
       newList[i] = dest; 
       } 
     int len2; 
     len2 = strlen(File); 
     newList[i] = File; 
     free(fileList); 
     int r = addedTo->numFilesIn; 
     r++; 
     addedTo->numFilesIn = r; 
     addedTo->filesIn = newList; 
     i = 0; 
     int *g; 
     g = addedTo->occursIn; 
     int count2; 
     count2 = addedTo->numFilesIn; 
     count2++; 
     int a[count2]; 
     for(i = 0; i < count2 -1; i++){ 
       a[i] = g[i]; 
     } 
     a[count2 - 1] = 1; 
     return 0; 
} 

i는 주목하는

헤드 -> occursIn [0] 광고

워드 크기 = 나 strlen 후

변화 (미량의 값 -> 단어);

저는 이유가 없습니다.

+0

최적화가 실행되면 어떻게됩니까? 그렇다면 디버거는 정확한 오류 라인을 가리 키기 위해 신뢰할 수 없습니다. 이 줄을 실행하면 정말 무관 한 무언가가 바뀐다. 제 말은 여러분이 포인터를 어딘가에서 혼동했다하더라도,'strcmp'가 아무 것도 언급하지 않는다고 생각합니다. 그러므로'a'는'head-> occurIn [0]'과 같은 위치에 있어야합니다. 이런 이상한 점에 대해서만 UB 및/또는 스택 손상에 대한 다른 옵션이 있습니다. – luk32

+0

@ luk32 네, 최적화를 켜고 껐을 때 일어난 일에 대해 잘못된 행을 썼습니다. 내 코드가 머리를 제외한 모든 노드에서 제대로 작동하는 것으로 보입니다. – atg963

+0

createNode() 및 addOccur() 함수에 대한 코드를 보여주십시오. –

답변

2

CreateNode() 함수에서 occurIn 배열에 대한 저장 영역을 할당하지 않습니다. 당신은 단순히 함수 내 로컬 배열을 선언하고 occursIn 포인터를 할당됩니다

int a[1]; 
a[0] = 1; 
new->occursIn = a; 

createNode 기능 반환, 그래서 그 시점에서 당신의 occursIn 포인터 값으로 가리키는 경우 [1] 사라질 배열 덮어 쓰게 될 수 있습니다.

스토리지가 createNode에 올바르게 할당 되었더라도 배열의 고정 크기를 설정했지만 모든 전략은 각 파일에 대한 요소가있는 배열에 따라 달라집니다. addOccurs에서는 새 파일에 대해 더 큰 새 배열을 할당하기 위해 아무 것도하지 않습니다.

전략을 재평가하고 배열 대신 목록을 사용하는 것으로 전환 할 수 있습니다.

+0

좋아, 이제는리스트를 구현하는 것이 훨씬 쉽다. 감사! – atg963