realloc()与动态数组后的意外行为

时间:2013-02-23 18:03:42

标签: c malloc realloc

我有一个任务,我想实现一个动态增长的数组,但我似乎遇到了realloc()的一些问题。我的代码工作,只要我实际上没有到达realloc()部分,由于某种原因,只有一些特定的值被更改为不同的东西。现在,如果我正在写/读出界限,我会期望行完全不同,但我似乎无法确定它。问题似乎在30-40行之间。这是代码:

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

预期输出如下(只要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()工作方式的假设。谢谢。

1 个答案:

答案 0 :(得分:1)

     unsigned long ID;

好的,IDunsigned long

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

嗯,%d的格式说明符是unsigned long吗?我不这么认为。

此外,feof并不预测未来的读取会成功,它只会告诉您已发生的事情。您需要检查fscanf的返回值,以查看读取是否成功。

最后,您的realloc调用分配了太多内存。你只是试图在S本身保留指针。