1

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

这是我的代码:

    #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;
    }
4

2 回答 2

2

以下行是错误的:

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

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

alunos = malloc( n * sizeof *alunos );

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

于 2013-09-28T13:42:11.110 回答
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;
}

因为它不是空终止的,所以像 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 );
于 2013-09-28T04:22:12.147 回答