At first memory was allocated and its address was assigned to the pointer Classe[i].total_alunos.nome and then the pointer was reassigned with the address of the memory allocated before the for loop:
Classe[i].total_alunos.nome = aluno.nome;
At least you need to use the string function strcpy like:
As of C89 casts on malloc are unnecessary, and under the C89 standard can suppress a useful diagnostic.
The type of the expression aluno.nome is char *, so sizeof( aluno.nome ) gives you the size of the pointer, not the size of the buffer it points to. Use strlen to get the length of the input string, then add 1 to account for the terminator.
The = operator is not defined to copy the contents of one array to another - in order to do that you have to use a library function like strcpy or memcpy, or copy elements individually in a loop. All you are doing here is assigning the pointer value stored in aluno.nome to Classe[i].total_alunos.nome, and in the process you're losing the reference to the memory you allocated with malloc, leading to a memory leak.
Finally, instead of using scanf to read string input, use fgets - it makes it easier to prevent a buffer overrun:
printf("Digite o nome do aluno\n");
fgets( aluno.nome, 20, stdin );
This will read at most 19 characters into aluno.nome and terminate the string. You can do that with scanf as well:
scanf( "%19s", aluno.nome );
but the lengths have to be hardcoded in the conversion specifier; you can't use * to specify a length at runtime like you can with printf.
发布评论
评论(2)
在这些语句中:
都产生了内存泄漏。
首先分配内存并将其地址分配给指针
Classe[i].total_alunos.nome
,然后使用for循环之前分配的内存地址重新分配指针:至少你需要使用字符串函数
strcpy
如下:前提是您为指针
Classe[i].total_alunos.nome
指向的数组分配了足够的空间,因为在此分配中您分配了记忆仅用于指针。即
sizeof(aluno.nome )
等于sizeof( char * )
。但要注意,仍然会出现内存泄漏,因为指针
aluno.nome
指向的内存没有被释放。没有多大意义
声明 DADOS_ALUNOS 类型的对象,然后动态分配内存
:相反,您可以仅声明一个字符数组,如下所示:
并在 for 循环中使用该数组:
In these statements:
there are produced memory leaks.
At first memory was allocated and its address was assigned to the pointer
Classe[i].total_alunos.nome
and then the pointer was reassigned with the address of the memory allocated before the for loop:At least you need to use the string function
strcpy
like:provided that you allocated enough space for the array pointed to by the pointer
Classe[i].total_alunos.nome
because in this allocationyou allocating memory only for pointer. That is
sizeof(aluno.nome )
is equal tosizeof( char * )
.However pay attention to that there will be still a memory leak because the memory pointed to by the pointer
aluno.nome
was not freed.There is no great sense to declare an object of the type
DADOS_ALUNOS
:and then dynamically allocate memory:
Instead you could declare just a character array as for example:
and use this array in the for loop:
几个问题。
首先,
从 C89 开始,对
malloc
的强制转换是不必要的,并且在 C89 标准下可以抑制有用的诊断。
表达式
aluno.nome
的类型为char *
,因此sizeof( aluno.nome )
为您提供指针的大小 ,而不是它指向的缓冲区的大小。使用strlen
获取输入字符串的长度,然后加 1 以表示终止符。接下来,更改
为
=
运算符未定义将一个数组的内容复制到另一个数组 - 为此,您必须使用strcpy
或 < code>memcpy,或在循环中单独复制元素。您在这里所做的就是将aluno.nome
中存储的指针值分配给Classe[i].total_alunos.nome
,在此过程中您将丢失对使用malloc
分配的内存,导致内存泄漏。最后,不要使用
scanf
读取字符串输入,而是使用fgets
- 它可以更轻松地防止缓冲区溢出:这将最多将 19 个字符读入
aluno .nome
并终止字符串。您也可以使用 scanf 来做到这一点:但长度必须在转换说明符中进行硬编码;您不能像使用
printf
那样在运行时使用*
指定长度。Several issues.
First, change
to
As of C89 casts on
malloc
are unnecessary, and under the C89 standard can suppress a useful diagnostic.The type of the expression
aluno.nome
ischar *
, sosizeof( aluno.nome )
gives you the size of the pointer, not the size of the buffer it points to. Usestrlen
to get the length of the input string, then add 1 to account for the terminator.Next, change
to
The
=
operator is not defined to copy the contents of one array to another - in order to do that you have to use a library function likestrcpy
ormemcpy
, or copy elements individually in a loop. All you are doing here is assigning the pointer value stored inaluno.nome
toClasse[i].total_alunos.nome
, and in the process you're losing the reference to the memory you allocated withmalloc
, leading to a memory leak.Finally, instead of using
scanf
to read string input, usefgets
- it makes it easier to prevent a buffer overrun:This will read at most 19 characters into
aluno.nome
and terminate the string. You can do that withscanf
as well:but the lengths have to be hardcoded in the conversion specifier; you can't use
*
to specify a length at runtime like you can withprintf
.