2013-02-23 2 views
0

동적으로 증가하는 배열을 구현하려는 할당이 있지만 realloc()에 문제가있는 것 같습니다. 내 코드는 실제로 realloc() 부분에 도달하지 않는 한 작동합니다. 어떤 이유로 특정 값만 다른 것으로 변경됩니다. 바운드를 쓰거나 읽는다면 이제 행이 완전히 달라질 것이라고 예상 할 수 있습니다. 그러나이를 정확히 지적 할 수는 없습니다. 문제는 30-40 행 사이에있는 것 같습니다. 여기realloc() 동적 배열을 사용한 후 의도하지 않은 동작

1 #include <stdio.h> 
2 #include <stdlib.h> 
3 #include <string.h> 
4 
5 typedef struct __student { 
6   unsigned long ID; 
7   char fname[33]; 
8   char lname[33]; 
9   float grade; 
10 } student; 
11 
12 void partA(FILE *fp) { 
13 
14   int i, r; 
15   i = r = 0; 
16   int N = 1000; 
17   student **S; 
18 
19   S = malloc(sizeof(student *) * N); 
20 
21   // While EOF has not been reached 
22   while(!feof(fp)){ 
23     // Allocate enough memory to hold each student struct 
24     S[i] = malloc(sizeof(student)); 
25     // Get each line and, using a scanset, get corresponding 
26     // data into respective struct fields 
27     fscanf(fp, "%d %[^,], %s %f", &S[i]->ID, S[i]->lname, S[i]->fname, &S[i]->grade); 
28     i++; // Get next line into a new struct 
29 
30     // If array size has been reached... 
31     if(i == N){ 
32       N *= 2; 
33       // Double it 
34       S = realloc(S, sizeof(student) * N); 
35       if(S == NULL) { 
36         // realloc has failed 
37         printf("Memory reallocation failed; Fatal error."); 
38         break; 
39       } 
40     } 
41   } 
42   r = i-1; 
43   // Output data 
44   printf("Name\t\t\t\t\t\t\t\t [ID]\t\t:\tGrade\n"); 
45   printf("___________________________________________________________________________________________________\n"); 
46   for(i=0; i<r; i++){ 
47     printf("%-32s %-32s [%lu]\t:\t%.3f\n", S[i]->fname, S[i]->lname, S[i]->ID, S[i]->grade); 
48     free(S[i]); 
49   } 
50 } 

내가 사용하고 입력 파일 : 다음은 코드가

58205720 Broke, Jim 95 
29571057 Crowe, John 88 
12957206 Moore, Kim 22 
59376027 Sarasvaki, Joe 79 
49027650 Morrigan, Tracy 68 
30773967 Trund, Geoffrey 99 
34850470 Perry, Tracey 77 
70209658 Oatnel, Skye 89 

예상 출력은 다음 (I은 N이 높은으로, 한 예를 얻을 수 할 있다. 라인의 실제 수보다 크고 realloc을 발생하지 않습니다()) 호출 될 :

Name                [ID]   :  Grade 
___________________________________________________________________________________________________ 
Jim        Broke       [58205720] :  95.000 
John        Crowe       [29571057] :  88.000 
Kim        Moore       [12957206] :  22.000 
Joe        Sarasvaki      [59376027] :  79.000 
Tracy       Morrigan       [49027650] :  68.000 
Geoffrey       Trund       [30773967] :  99.000 
Tracey       Perry       [34850470] :  77.000 
Skye        Oatnel       [70209658] :  89.000 

그러나을, 나는 N을 설정하는 경우 = 3, 다음을 얻습니다 :

Name                [ID]   :  Grade 
___________________________________________________________________________________________________ 
Jim        Broke       [58205720] :  95.000 
John        Crowe       [29571057] :  88.000 
Kim        Moore       [12957206] :  22.000 
Joe        Sarasvaki      [59376027] :  79.000 
Tracy       Morrigan       [49027650] :  68.000 
Geoffrey       Trund       [30773967] :  99.000 
Tracey       Perry       [231963084454]  :  77.000 
Skye        Oatnel       [231998443642]  :  89.000 

나는 무슨 일이 벌어지고 있는지에 관해서는 상당히 실망 스럽습니다. gdb를 사용하여 스택과 로컬 값을 검사 해 보았습니다. 그러나 아직 많은 행운을 얻지 못했습니다. 나는 또한 ID가 왜 손상 될 유일한 이유인지에 대해서도 모순된다. realloc()에 의해 얻은 새로운 공간에 대한 포인터를 반환하는 별도의 함수를 만들어야 할 필요가 있습니까? 나는 가능한 한 압축 된 코드를 유지하기를 원했기 때문에 맨 페이지가 realloc()의 작동 방식에 대한 나의 가정을 뒷받침하는 것 같았 기 때문에 먼저이 방법을 시도했다. 고맙습니다.

+4

중요한 문제는 아니지만'S = realloc (S, sizeof (student) * N);은'S = realloc (S, sizeof (student *) * N); '이어야합니다. 할당하는 메모리는 학생이 아니라 학생을 가리키는 포인터입니다. –

+0

'feof'는 당신이 생각하는 것처럼 작동하지 않습니다 ... –

+0

Carl Norum이 말하는 것을 증폭시키기 위해, 미래의 읽기가 성공할지를 예측하기 위해'feof'를 사용할 수 없습니다. 'fscanf'의 반환 값을 확인해야합니다. 다시 한번 말하지만, 그것은 아마도 당신의 주요 문제가 아닙니다. –

답변

1
 unsigned long ID; 

좋아는 IDunsigned long입니다.

 fscanf(fp, "%d %[^,], %s %f", &S[i]->ID, S[i ... 

%dunsigned long의 형식 지정자입니까? 나는 그렇게 생각하지 않는다.

또한 feof은 향후 읽기가 성공할 것이라고 예측하지 않으며 이미 발생한 상황 만 알려줍니다. 읽기 성공 여부를 확인하려면 반환 값 fscanf을 확인해야합니다.

마지막으로 사용자의 realloc 호출이 너무 많은 메모리를 할당합니다. S 자체에서만 포인터를 잡으려고합니다.

+0

답 및 위의 의견에 감사드립니다. 나는 당신이 그것을 제공 한 이후로 대답으로 표시 할 것입니다. On point : 나는 여러 가지 다른 기능의 파일을 가지고 있는데, 실제로 그 파일에 % lu를 사용했습니다. 왜 이것이 업데이트되지 않았는지 나는 잘 모르겠지만 잡은 것에 감사드립니다! – user991710