如何使用带有指针的结构的free?

时间:2013-09-28 03:53:45

标签: c

我正在尝试对结构内部的指针使用free,然后我对结构使用free,它似乎是正确的但我得到了这个错误:free():next next(fast);错误消息msg更大但我认为这足以知道这是关于错误内存。

这是我的代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    typedef struct{
        char *nome;
        char *endereco;
        char *matricula;
    }Estudante;

    char *strAlloc( int n ){
        return ( char *) malloc( n * sizeof( char * ));
    }

    int lineReader( char **str ){

        char c;
        int length = 10, strI = 0;

        getchar();

        *str = strAlloc( length );
        while ( 1 ){

            c = getchar();

            if ( strI+1 == length ){

                length += 10;

                *str = ( char * ) realloc( *str, length * sizeof( char *));

                if( *str == NULL){
                    printf("Faltou memoria\n");
                    return 0;
                }
            }
            if ( c == '\n' ) break;

            (*str)[ strI++ ] = c;
        }

        return strI;
    }

    int main(){



        Estudante *alunos;
        int n, length, i, j;
        char *str;
        char c;

        printf("Digite a quantidade de alunos:\n");
        scanf(" %d", &n);

        alunos = ( Estudante * ) malloc( n * sizeof( Estudante * ));

        for (i = 0; i < n; ++i){

            printf("Digite o nome do aluno %d:\n", i+1);

            length = lineReader ( &str );

            alunos[ i ].nome = strAlloc( length );
            strcpy( alunos[ i ].nome, str );

            printf("Digite o endereço do aluno:\n");

            length = lineReader ( &str );
            alunos[ i ].endereco = strAlloc( length );
            strcpy( alunos[ i ].endereco, str );

            printf("Digite a matricula do aluno:\n");

            length = lineReader ( &str );
            alunos[ i ].matricula = strAlloc( length );
            strcpy( alunos[ i ].matricula, str );

            printf("\n");
        }

        free( str );

        for (i = 0; i < n; ++i){

            printf("Dados do aluno %d\n", i+1);
            printf("Nome: %s\n", alunos[ i ].nome );
            printf("Endereço: %s\n", alunos[ i ].endereco );
            printf("matricula: %s\n\n", alunos[ i ].matricula );

            free( alunos[ i ].nome );
            free( alunos[ i ].endereco );
            free( alunos[ i ].matricula );
        }

        free( alunos );
        alunos = NULL;

        return 0;
    }

2 个答案:

答案 0 :(得分:2)

以下行错误:

alunos = ( Estudante * ) malloc( n * sizeof( Estudante * ));

您需要为n struct Estudante分配空间,而不是为n个指针分配空间。您可以使用惯用语来避免此错误:

alunos = malloc( n * sizeof *alunos );

另请注意,虽然在C ++中有必要转换malloc的返回值,但在C中这样做既不必要也不可取。(在80年代后期,提供那些日子已经过去了。)

答案 1 :(得分:0)

你有正确的形式来释放结构,其他东西必须先破坏堆。

看起来您的字符串不会以空值终止 在lineReader

if ( c == '\n' ) break;

应该是

if ( c == '\n' ) {
(*str)[strI] = '\0'; //Not incrementing strI because the null character doesn't count towards the string size
break;
}

因为它不是null终止,所以像strcpy这样的字符串函数可能会超出它的预期。如果可用,请考虑使用strncpy。

另外,free(str)应该在这个for循环中吗? lineReader()每次都会继续分配一个新字符串而不释放旧字符串。

for (i = 0; i < n; ++i){

        printf("Digite o nome do aluno %d:\n", i+1);

        length = lineReader ( &str );

        alunos[ i ].nome = strAlloc( length );
        strcpy( alunos[ i ].nome, str );

        printf("Digite o endereço do aluno:\n");

        length = lineReader ( &str );
        alunos[ i ].endereco = strAlloc( length );
        strcpy( alunos[ i ].endereco, str );

        printf("Digite a matricula do aluno:\n");

        length = lineReader ( &str );
        alunos[ i ].matricula = strAlloc( length );
        strcpy( alunos[ i ].matricula, str );

        printf("\n");
    }

    free( str );