我有这个功能,我重新定位内存,但是当我想读取字符串时,它没有工作=>错误 学生是一个结构
void insertStudent(Student **myStudents, int *size)
{
int newSize = *size + 1;
*myStudents = (Student*)realloc(myStudents, newSize*sizeof(Student));
printf("Enter your grade: ");
scanf("%f", &(*myStudents)[*size - 1].nota);
printf("Enter your first name: ");
scanf("%s", &(*myStudents)[newSize-1].firstName);
printf("Enter your second name: ");
scanf("%s", &(*myStudents)[*size - 1].lastName);
//Generate a new code
/*int code = rand() % 1+1000;
int ok = 0;
while (ok == 0)
{
ok = 1;
for (int i = 0; i < *size; i++)
if ((*myStudents)[i].cod == code)
{
code = rand() % 1 + 1000;
ok = 0;
}
}*/
(*myStudents)[*size-1].cod = 7;
printf("Your code is: %d. Do not forget it! ", 7);
}
答案 0 :(得分:4)
void insertStudent(Student **myStudents, int *size)
{
*myStudents = (Student*)realloc(myStudents, newSize*sizeof(Student));
// ^ <- look here
这是指向学生的指针的指针。 realloc()
期望指向最初分配的数据的指针,所以你肯定必须在这里传递*myStudents
!
还要更改代码以使用临时变量。 realloc()
可能会因错误而返回NULL
,在这种情况下,原始内存仍然已分配,您必须free()
。
为了计算大小,最好使用sizeof
(newSize * sizeof **myStudents
)的表达式语法,因为这可以防止以后更改类型时出错。
对于尺码,您应该始终使用size_t
,因为这可以保证保持任何可能的尺寸(int
不是......)
进一步的注意事项:转换为void *
和从void insertStudent(Student **myStudents, size_t *size)
{
size_t newSize = *size + 1;
Student *newStudents = realloc(*myStudents, newSize * sizeof *newStudents);
if (!newStudents)
{
free(*myStudents);
*myStudents = 0;
return; // check for this error in calling code
}
*myStudents = newStudents;
*size = newSize;
// [...]
}
转换为C中的隐式,并且它arguably better style不会明确地编写此转换。
总而言之,代码应该像这样编写
{{1}}
答案 1 :(得分:1)
您正在重新分配到myStudents
。这不是你的意图,也是不可能的。
void *realloc(void *ptr, size_t size);
否则,如果
ptr
与之前返回的指针不匹配 内存管理功能,或者如果空间已被释放 调用free或realloc函数,行为未定义。如果 无法分配新对象的内存,旧对象则不能 取消分配,其价值不变。
之前您有未定义的行为,您没有传递最初分配的内存地址。而是你传递了一个局部变量。您有未定义的行为。
Student* t = realloc(*myStudents, newSize*sizeof(Student))
if(t){
*myStudents = t;
(*size)++;
}
else {
perror("realloc failed");
free(*myStudents);
exit(EXIT_FAILURE);
}
此外,当您增加内存时,如果呼叫成功,您应该增加内存。然后在整个代码中始终访问*size-1
,它更容易处理和完成。
上面显示的正确方法。如果realloc
返回NULL
,您将不会丢失对已分配内存的引用。另外,建议检查realloc
的返回值。在这种情况下,投射是多余的 - 不要这样做。
在scanf
中你可以简单地写
scanf("%s",(*myStudents)[newSize-1].firstName);
否则你传递char (*)[]
它预期char*
。
答案 2 :(得分:1)
realloc()
需要指向要重新分配的内存的指针,*myStudents
而非myStudents
。
更改
*myStudents = (Student*)realloc(myStudents, newSize*sizeof(Student));
到
*myStudents = (Student*)realloc(*myStudents, newSize*sizeof(Student));