2017-01-18 2 views
0

세그먼트 화 오류가 할당되지 않아야하지만 할당되지 않아야하지만 내 코드에서이 오류를 트리거하는 것을 찾을 수없는 메모리에 액세스하려고한다는 것을 알고 있습니다. 다른 답변은 Valgrind 사용을 지적했지만 로컬 컴퓨터에 컴파일러가 없으며이를 School Server에 설치할 수있는 관리자 권한이 없습니다. 오류가 발생한 위치를 알려주는 도움을 주시면 감사하겠습니다. 다음은 헤더 파일세그먼트 화 오류 추적 11

/* 
* File:  set.h 
* 
* Copyright: 2015, Darren C. Atkinson 
* 
* Description: This file contains the public function and type 
*    declarations for a set abstract data type for strings. A 
*    set is an unordered collection of distinct elements. 
* 
*    Note that this file uses the bool type, but does not define 
*    it. You should include <stdbool.h> beforehand. 
*/ 

# ifndef SET_H 
# define SET_H 

typedef struct set 
{ 
    char **elts; //char * array containing strings 
    int length; //total length of array 
    int size; //number of strings within array 
}SET; 


SET *createSet(int maxElts); 

void destroySet(SET *sp); 

int numElements(SET *sp); 

bool hasElement(SET *sp, char *elt); 

bool addElement(SET *sp, char *elt); 

bool removeElement(SET *sp, char *elt); 

# endif /* SET_H */ 

내 코드로 컴파일 주어진 테스트 파일입니다.

/* 
* File:  unique.c 
* 
* Copyright: 2015, Darren C. Atkinson 
* 
* Description: This file contains the main function for testing a set 
*    abstract data type for strings. 
* 
*    The program takes two files as command line arguments, the 
*    second of which is optional. All words in the first file 
*    are inserted into the set and the counts of total words and 
*    total words in the set are printed. If the second file is 
*    given then all words in the second file are deleted from 
*    the set and the count printed. 
*/ 

# include <stdio.h> 
# include <stdlib.h> 
# include <string.h> 
# include <stdbool.h> 
# include "set.h" 


/* This is sufficient for the test cases in /scratch/coen12. */ 

# define MAX_SIZE 18000 


/* 
* Function: main 
* 
* Description: Driver function for the test application. 
*/ 

int main(int argc, char *argv[]) 
{ 
    FILE *fp; 
    char buffer[BUFSIZ]; 
    SET *unique; 
    int words; 


    /* Check usage and open the first file. */ 

    if (argc == 1 || argc > 3) { 
     fprintf(stderr, "usage: %s file1 [file2]\n", argv[0]); 
     exit(EXIT_FAILURE); 
    } 

    if ((fp = fopen(argv[1], "r")) == NULL) { 
     fprintf(stderr, "%s: cannot open %s\n", argv[0], argv[1]); 
     exit(EXIT_FAILURE); 
    } 


    /* Insert all words into the set. */ 

    words = 0; 
    unique = createSet(MAX_SIZE); 

    while (fscanf(fp, "%s", buffer) == 1) { 
     words ++; 
     addElement(unique, buffer); 
    } 

    printf("%d total words\n", words); 
    printf("%d distinct words\n", numElements(unique)); 
    fclose(fp); 


    /* Try to open the second file. */ 

    if (argc == 3) { 
     if ((fp = fopen(argv[2], "r")) == NULL) { 
      fprintf(stderr, "%s: cannot open %s\n", argv[0], argv[2]); 
      exit(EXIT_FAILURE); 
     } 


     /* Delete all words in the second file. */ 

     while (fscanf(fp, "%s", buffer) == 1) 
      removeElement(unique, buffer); 

     printf("%d remaining words\n", numElements(unique)); 
    } 

    destroySet(unique); 
    exit(EXIT_SUCCESS); 
} 

마지막으로 오류가 발생한 코드입니다. 함수

/* 
* File:  unsorted.c 
* 
* 
* Description: This file contains the definitions for a simple interface for a SET structure that contains a list of strings as well as the list size. 
*/ 
#include <assert.h> 
#include <stdbool.h> 
#include <string.h> 
#include <stdlib.h> 
#include "set.h" 

int findElement(SET *sp,char *elt); 

struct SET 
{ 
    char **elts; //char * array containing strings 
    int length; //total length of array 
    int size; //number of strings within array 
}; 

//initializes SET 
//O(1) efficiancy 
SET *createSet(int maxElts) 
{ 
    SET *sp; 
    sp->elts = (char **) malloc(sizeof(char*)*maxElts); 
    assert(sp->elts!=NULL); 
    sp->size = 0; 
    sp->length = maxElts; 
    return sp; 
} 

//frees all strings from memory and then the containing array 
//O(n) efficiancy n==sp->size 
void destroySet(SET *sp) 
{ 
    while (sp->size > 0) free(sp->elts[--sp->size]); 
    free(sp->elts); 
} 

//return the number of strings within the array 
//O(1) efficiency 
int numElements(SET *sp) 
{ 
    return sp->size; 
} 

//Sequentially searches SET for elt and return the array location, if not found -1 is returned 
//O(n) efficiency n=sp->size 
int findElement(SET *sp,char *elt) 
{ 
    int i =0; 
    for (i; i < sp->size; i++) 
    { 
     if (strcmp(sp->elts[i],elt) == 0) return i; 
    } 
    return -1; 
} 

//appends elt on the end of the array within SET 
//O(1) efficiency 
bool addElement(SET *sp, char *elt) 
{ 
    if (findElement(sp, elt) != -1) return false; 
    if (sp->size == sp->length) return false; 
    sp->elts[sp->size] = (char*) malloc(sizeof(char)*(strlen(elt)+1)); 
    assert(sp->elts[sp->size]!=NULL); 
    sp->size = sp->size +1; 
    return true; 
} 

//returns true if SET contains elt otherwise return false 
//O(n) efficiency n=sp->size 
bool hasElement(SET *sp, char *elt) 
{ 
    if (findElement(sp,elt) == -1) return true; 
    return false; 
} 

//finds elt and removes it from array if present, then moves all following strings forward in the array 
//O(n) efficiency n=sp->size 
bool removeElement(SET *sp,char *elt) 
{ 
    int loc = findElement(sp,elt); 
    if (loc == -1) return false; 
    free(sp->elts[loc]); 
    while (loc <sp->size) 
    { 
     sp->elts[loc] = sp->elts[loc+1]; 
     loc++; 
    } 
    sp->size=sp->size-1; 
    return true; 
} 
+1

(이미 하나가있을 수 있습니다) 및 Valgrind의로 이어질 수 있습니다. – synchronizer

+2

의존하는 원격 컴파일 및 실행 기능이있는 경우 문제를 나타내는 가능한 가장 작은 프로그램으로 줄이기 위해 프로그램을 비트 단위로 정리할 수 있습니다. 종종이 운동은 문제의 본질을 발견하는 데 도움이되지만 결과가 아닐지라도 결과는 여기에서 찾는 것과 같은 종류의 [mcve] 일 것입니다. –

+1

'(fscanf (fp, "% s", 버퍼)'와 함께,'fscanf (fp, "% XXXs", buffer)'또는 무엇이든지'BUFISZE -1'로 제한하지 않겠습니까? – chux

답변

0

: createSet는()

가변 SP는 구조체 세트의 인스턴스를 가리 키도록 초기화되지 않는다.

그래서 코드는 다음과 비슷해야합니다
SET *sp = NULL; 
if(NULL == (sp = malloc(sizeof(struct set))) 
{ 
    perror("malloc for struct set failed"); 
    exit(EXIT_FAILURE); 
} 

그렇지 않으면 SP 이제까지 임의 주소는 위치에있는 스택에 무엇을 포함합니다.

이 정의되지 않은 동작이며, 독방 감금 오류 당신은 아마 컴파일러를 설치하는 방법을 파악해야 이벤트

+0

이것은 다소 모호한 코드입니다. 'SET * sp = malloc (...);을 쓰지 않는 이유는 무엇인가? if (sp == NULL) {...'? – Lundin

+0

@ Lundin, 이런 종류의 문장은 매우 일반적으로 사용되며 나중에 코드 유지자가 오류 검사에서 할당을 분리하는 것을 방지하는 데 도움이됩니다. – user3629249

+0

아니요, 일반적으로 사용되지 않습니다. 할당과 오류 검사를 같은 식으로 계속 사용하려는 이유가 없습니다. 만약 당신이'SET * sp = malloc (...); if (sp == NULL)'이고 나중에 약간 지연되면이 두 문장 사이에 분기 코드를 추가하기로 결정할 때 C 코드를 유지하기에는 너무 무능하기 때문에 도움을 줄 수있는 방법이 없습니다. 무능한 사람들이 그것을 유지할 것이라고 의심하기 때문에 코드를 난독화할 이유가 없습니다.대신 유능한 C 프로그래머가 코드를 유지 관리한다고 가정합니다. – Lundin