c - 使用动态数组进行 realloc() 后的意外行为

标签 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() 工作方式的假设。谢谢。

最佳答案

     unsigned long ID;

好的,ID 是一个unsigned long

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

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

此外,feof 不会预测 future 的读取会成功,它只会告诉您已经发生的情况。需要检查fscanf的返回值来判断读取是否成功。

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

关于c - 使用动态数组进行 realloc() 后的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15043754/

相关文章:

c - sscanf 直到 c 中的文件末尾

c - 如何判断星号的使用是否与指针相关?

C - free() 不会删除我的结构 malloc

c - 在 C 中重新分配指向结构的指针数组

c++ - 为什么使用 std::vector 而不是 realloc?

C 按值查找字符串

c++ - 使用 gcc 将字符串文字的编码设置为 latin1

c - malloc 看起来不适用于我的程序

c - 警告 : Incompatible pointer types assigning to 'node_t *' (aka 'struct node *' ) from 'mode_t' (aka 'unsigned int *' )

c - Realloc 使我的程序崩溃