strlen and malloc: C memory leaks

2019-03-05 14:15发布

问题:

This question is null and void! I was not properly freeing the Students! I will accept the answer that revealed this to me as quickly as I am allowed!

I'm new to C and am practicing malloc. In the grand scope, I'm writing a linked list library; this create_student function is among many functions I'm going to use to test my linked list library. The problem is...I run valgrind and call this function and it indicates there are several memory leaks caused by that first malloc. It all looks solid, best to my knowledge:

typedef struct Student
{
        char* first_name; /* This will be malloc'd!*/
    char* last_name; /* This will also be malloc'd */
    int grade;
    long id;
} Student;


Student* create_student(const char* first_name, const char* last_name, int grade, long gtid)
{

        /* First allocate a student on the heap */
        Student *newStudentp = (malloc(sizeof(Student)));


    /* Allocate enough space for the first and last names */
    newStudentp -> last_name = (malloc(strlen(last_name)));
    newStudentp -> first_name = (malloc(strlen(first_name)));



        // AND copy the first and last name to the first and last name fields in the struct   
    strncpy(newStudentp -> first_name, first_name, strlen(first_name));
    strncpy(newStudentp -> last_name, last_name, strlen(last_name));



        /* Set the grade and id */
    newStudentp -> grade = grade;
    newStudentp -> id = id;

        */ 
    return newStudentp;
}

My error messages from valgrind (there are several) look like this:

==4285==    9 bytes in 1 blocks are definitely lost in loss record 8 of 8
==4285==    at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==4285==    by 0x804855B: create_student (test.c:24)
==4285==    by 0x8048748: main (test.c:109)

line 24 is the

newStudentp -> last_name = (malloc(strlen(last_name))); 

line.

Is there some fundamental misuse of strlen by me that is causing an error?

回答1:

There are a few problems here:

    newStudentp -> last_name = (malloc(strlen(last_name)));
    newStudentp -> first_name = (malloc(strlen(first_name)));

strlen only gives the length up to but not including the terminating '\0'. But that must be stored too, so you should use strlen(last_name) + 1 in both cases.

Also, your strncpy() should better be done using the size of the allocated buffer and not of the source string, so you can avoid writing past the high boundary of the array. But since you already used malloc(strlen(...) + 1), you can simply use strcpy() here.