这是我的完整代码,看起来很有效,但效果不好。 我会接受任何代码,就像这样。
首先,代码有效,但是当我想在结构中添加第三个名称时,它会崩溃。
还有其他办法吗?
我需要结构,因为在将来,我想添加一些其他参数,如年龄,平均值,性别等。
请帮帮我。
//The student table
typedef struct students {
char name[50];
} students;
//Global params
int scount = 0;
students *s;
//Basic functions
void addNewStudent();
int main()
{
int loop = 1;
char in;
int ch;
printf("Willkommen.\n Wahlen Sie bitte von die folgenden Optionen:\n");
while (loop)
{
printf("\t[1] Neue Student eingeben\n");
printf("\t[9] Programm beenden\n");
scanf(" %c", &in);
while ((ch = getchar()) != '\n');
switch (in)
{
case '1':
addNewStudent();
break;
case '9':
loop = 0;
break;
default: printf("------\nOption nicht gefunden.\n------\n");
break;
}
}
free(s);
return 0;
}
void addNewStudent()
{
int index = 0;
if (scount == 0)
{
s = (students*)malloc(sizeof(students));
}
else
{
realloc(s, sizeof(students) * scount);
}
printf("Geben Sie Bitte die Name:\n");
fgets(s[scount].name, sizeof(s[scount].name), stdin);
while (s[scount].name[index] != '\n')
{
index++;
}
s[scount].name[index] = '\0';
scount++;
}
我正在使用Visual Studio。
感谢您的帮助!
答案 0 :(得分:4)
students *mynew= realloc(s, sizeof(students)* (scount+1));
if( mynew != NULL )
s=mynew;
Otehrwise你有内存泄漏。您没有使用realloc
的返回值。
请勿转换malloc
的返回类型。
根据标准§7.22.2.35
void *realloc(void *ptr, size_t size)
realloc
函数释放ptr
指向的旧对象 返回指向size
指定大小的新对象的指针。
最好不要使用调用malloc
的相同指针变量,因为如果它失败,你也将失去对旧的引用(除非它通过其他方式存储)。
此外,您没有检查malloc
的返回值。
s = malloc(sizeof(students));
if( s == NULL ){
frpntf(stderr,"%s","Memory allocation failed");
exit(1);
}
另外,您应该检查fgets()
的返回值。
if( fgets(s[scount].name, sizeof(s[scount].name), stdin) == NULL){
fprintf(stderr,"%s","Error in input");
exit(1);
}
还试图编译你的代码,它显示了这个
warning: ignoring return value of ‘realloc’, declared with attribute warn_unused_result [-Wunused-result] realloc(s, sizeof(students) * scount); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
编译时尽量不要忽略任何警告信息。它显示了你遇到的问题。
scount+1
realloc
?{/ h3>
重新分配总体思路时,增加学生人数。为此,您需要为学生分配额外的内存。这就是代码中scount+1
的原因。(realloc
)。
while (s[scount].name[index] != '\n')
{
index++;
}
s[scount].name[index] = '\0';
你也可以这样做
size_t len = strlen(s[scount].name);
if(len){
s[scount].name[len-1]='\0';
}
从标准§7.21.7.2
了解原因char *fgets(char * restrict s, int n,FILE * restrict stream)
fgets
函数最多读取的数量少于1 由n
指向stream
的流中s
指定的字符\0
指向的数组。 a后没有读取其他字符 换行符(保留)或文件结束后。 空 在读入最后一个字符后立即写入字符 数组。
string
字符已存在于输入的\0
中。您可以获得它的长度,但是您知道\n
之前的那个是您通过按<输入的\0
字符 1 kbd>输入键。我们用n-1
覆盖它。
1。这是通常的情况,但不是唯一的。有两种情况可能不适合查看该事物。
输入行在'\n'
之前有\0
个或更多字符。 \n
之前的那个不是'\n'
,而是用户输入的某个字符。
最后一行是一个可能没有\n
的流。 (stdin关闭)。在这种情况下,输入也不包含\n
。
因此,在这些情况下,删除s[scount].name[strcspn(s[scount].name, "\n")] = '\0';
的想法会失败。在评论中讨论。 (chux)子>
\0
link 的解释是,如果给出s[scount].name[SIZE_MAX]
作为输入,那么我们基本上会写入size_t strcspn(const char *s1, const char *s2)
,这是不合需要的。
来自标准§7.24.5.3
strcspn
s1
函数计算最大初始值的长度s2
指向的字符串段,完全由。{1}组成 字符不是来自1>}指向的字符串。
答案 1 :(得分:4)
如何在C中正确地malloc结构?
p = malloc(sizeof *p);
if (p == NULL) Handle_OutOfMemory();
如何在C中正确地重新分配结构?
void *t = realloc(p, sizeof *p * number_of_elements);
if (t == NULL && number_of_elements > 0) {
Handle_OutOfMemory();
} else {
p = t;
}
p
指向某些struct
。请注意上面的没有该类型的编码。
OP'主要问题是没有使用realloc()
的返回值并且分配1-too-small
// realloc(s, sizeof(students) * scount);
s = realloc(s, sizeof *s * (scount+1)); // or use above code with check for out-of-memory.
答案 2 :(得分:2)
realloc
返回一个你需要保留的新指针:
students* snew = realloc(s, sizeof(students) * (scount + 1));
if (!snew) {
free(s); // If there is not enough memory, the old memory block is not freed
// handle out of memory
} else {
s = snew;
}
答案 3 :(得分:1)
你没有回来分配它!看看<custom-ion-item>
的工作原理。在进行重新分配之后,需要将指针分配回来。
realloc
根据定义,realloc返回一个void指针,但你没有收集它。
if (scount == 0)
{
s = (students*)malloc(sizeof(students));
}
else
{
students *temp = realloc(s, sizeof(students) * (scount+1));
if(temp == NULL){
free(s);
}
else{
s = temp;
}
}
如果空间不足, realloc会返回void *realloc(void *ptr, size_t size);
。因此,当您确定它不是NULL
只需在上面做一个小改动,你的代码就像一个魅力!
干杯!