2017-02-05 5 views
1

편집 : 질문에 대한 답변, 내 첫 루프에 대한 오타가있었습니다. 그것을 잡는 것에 대해 모두 감사합니다.
uni 용 C 프로젝트를 만들고 있는데, 알아낼 수없는 문제가 있습니다. 프로그램의 한 섹션에서 구조체 (일명 "스탬프")에서 2D 문자 배열로 심볼 문자열을 읽어야합니다. 나는 텍스트 파일에서 문자열을 fscanf 할 때fscanf 내 C 프로그램을 충돌, 이유는 모르겠어요.

stamp_t * read_stamp_type1(FILE * fptr) 
{ 
    //variable declaration 
    int r = 0, c = 0; 

    //creating a struct stamp_t and mallocing memory 
    stamp_t *newstamp1; 
    newstamp1 = malloc(sizeof(stamp_t)); 

    //reading in values for the rows and columns of the "stamp" to be read in 
    fscanf(fptr, "%d %d\n", &r, &c); 

    //storing these values 
    newstamp1->num_rows = r; 
    newstamp1->num_cols = c; 

    //creating memory for newstamp1's grid 
    newstamp1->grid = malloc(sizeof(char *) * (r)); 
    for(int i=0; i < c; i++) 
     newstamp1->grid[i] = malloc(sizeof(char) * (c+1)); 

    //string to temporarily store input 
    char rowvalues[c+1]; 

    //Note: Everything works up until this point 
    //the below lines crash the program every time 
    for(int i = 0; i < r; i++) 
    { 
     fscanf(fptr, "%s", rowvalues); 
     for (int j=0; j < c; j++) 
      strcpy(newstamp1->grid[i], rowvalues); 

    } 

    free(rowvalues); 

    return(newstamp1); 

} 

어떤 이유는 프로그램을 충돌 (또는 적어도 그게 내가 ... 원인은 무엇을 생각) : 여기 내 기능의 코드입니다.
참고로 , 여기에 구조체의 선언입니다 :

// A structure for holding a stamp 
typedef struct 
{ 
    // The size of the contents of this stamp. 
    int num_rows; 
    int num_cols; 

    // A 2D array of characters for a stamp. 
    char **grid; 
} stamp_t; 

을 그리고 여기에 프로그램의 입력 :

3 4 
.#[email protected] 
#.#. 
.#[email protected] 

어떤 조언을 크게, 내가 어떤 문제를 찾을 수 없습니다 주시면 감사하겠습니다 코드와 함께. 난 rowvalues ​​배열 (rowvalues ​​[0] = 'c';) 잘 작동합니다 각 값을 수동으로 값을 할당 할 시도했다. 3 행의 기호를 2D 배열 인 newstamp1.grid에 읽어 들일 필요가 있습니다. 나는 디버거를 돌렸고 허용되지 않는 메모리에 쓰기를 시도했다. ("Access violation writing location"). 나는 내 교수에게 이메일을 보냈지 만 지난 주 동안 수업에 들지 않았으며 이메일에 응답하지 않았습니다 ...
미리 감사드립니다. 당신은 당신의 forc 배속으로 반복 한 후 r 항목을 할당하고

newstamp1->grid = malloc(sizeof(char *) * (r)); 
for(int i=0; i < c; i++) 
    newstamp1->grid[i] = malloc(sizeof(char) * (c+1)); 

:

+0

관련없는 메모리 오류 일 수 있습니다. valgrind에서 코드를 실행하여 비 휘청 거리는 것을 발견했는지 확인하십시오. – templatetypedef

+0

valgrind 만 사용하고 메시지를 읽고 이해하는 경우. 이 중 어느 것도 대단히 어렵지 않습니다. 나는 열 살짜리가 그것을 성취 할 수 있다고 생각한다. – Sebivor

+0

당신의 유용한 입력에 감사드립니다. @Seb, 그 논리와 함께 저는 지금 우리 대학 교수에게 모든 교수들을 해고하고 학생들에게 valgrind를 설치하라고 말할 수있는 편지를 쓸 것입니다! 그들에게 많은 돈을 저축해야합니다. 우리는 모든 사람이 타고난 프로그래밍 지식으로 태어났다는 사실을 알지 못했고, 일을하는 법을 배울 필요가 없습니다. 10 세에 어떤 프로그램을 쓰는지 알고 싶습니다. 누군가의 도움없이 코드 작성을 배웠다는 것을 진심으로 의심합니다. –

답변

2

코드의이 부분은 넌센스이다. 이 값은 r이거나 둘 다 c이어야합니다. 나는 거기에 정확한 조건이 i < r라고 생각합니다.

모스크바의 블라드 (Vlad)가 지적했듯이, 코드에는 또 하나의 버그가 있습니다. 이 아니기 때문에 최종 free이 없어야합니다. 그리고 for-j 라인을 생략 할 수도 있습니다. (그러나 그것은 단지 unneededly 동일한 코드를 반복, 오류가 발생하지 않아야합니다.) 우선 들어

+0

와우, 나는 그 오류를 잡지 못했다. 감사! 그것은 많은 도움이됩니다. –

+1

'sizeof (char)'는 항상 1이고'newstamp1-> grid [i] = malloc (c + 1);만으로 충분할 수도 있습니다. 이것은 또한'malloc()'도 항상 검사해야 함을 나타냅니다. – RoadRunner

3

newstamp1->grid = malloc(sizeof(char *) * (r)); 
for(int i=0; i < c; i++) 
      ^^^^^^ 
    newstamp1->grid[i] = malloc(sizeof(char) * (c+1)); 

for(int i=0; i < r; i++) 
      ^^^^^^ 

이를이 있어야이 루프에 오타가 루프

for (int j=0; j < c; j++) 
     strcpy(newstamp1->grid[i], rowvalues); 

은 적합하지 않습니다. 당신이 단지

strcpy(newstamp1->grid[i], rowvalues); 

을 의미 아니면 당신이 파일의 각 행이 c 문자열을 포함하는 경우 (즉, 문자열의 2 개 차원 배열) 3 차원 문자 배열을 할당 할 필요가 보인다.

그리고이 문장

free(rowvalues); 

은 잘못된 것입니다. 변수 rowvalues에는 자동 저장 기간이 있습니다. 따라서 함수를 free이라고 부를 수는 없습니다.

+0

그래, 나는이 대답을 좋아한다. 그것은 내 것보다 더 자세합니다. :-) –

+0

이것은 훌륭하게 작동했습니다 ... 미안합니다. malloc'ing rowvalues ​​일 때부터 무료 진술을 남겨 놓았습니다. 나중에 정적 할당으로 변경했습니다. 정말 고마워, 내가 처음 루프 오타가 문제가되었다고 생각했는데, 왜냐하면 내가 4를 필요로 할 때마다 3 칸을 만들었 기 때문이다. 정말로 감사하고, 지금은 잘 작동하고있다. :) –