【问题标题】:strlen and malloc: C memory leaksstrlen 和 malloc:C 内存泄漏
【发布时间】:2011-10-12 01:43:00
【问题描述】:

本题无效!我没有适当地释放学生!我会尽快接受向我透露这一点的答案!

我是 C 新手,正在练习 malloc。在宏大的范围内,我正在编写一个链表库;这个 create_student 函数是我将用来测试我的链表库的众多函数之一。问题是......我运行 valgrind 并调用这个函数,它表明第一个 malloc 导致了几个内存泄漏。据我所知,这一切看起来都很可靠:

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

我来自 valgrind 的错误消息(有好几个)如下所示:

==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)

第 24 行是

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

行。

我对 strlen 的某些基本滥用是否导致错误?

【问题讨论】:

  • free你的学生结构怎么样?
  • 请注意strlen 返回的字符串长度not 包括终止符'\0'
  • 您的malloclast_name 应分配strlen(last_name)+1 字符以便为'\0' 包含空间(first_name 相同)
  • 您可能还希望为比strlen 返回的字符多一个字符分配内存,因为您需要空间用于终止'\0' 字符。
  • 如果您刚刚分配了适量的空间,您可以安全地使用strcpy

标签: c memory memory-management memory-leaks


【解决方案1】:

这里有几个问题:

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

strlen 只给出不超过但不包括终止 '\0' 的长度。但这也必须存储,所以在这两种情况下都应该使用strlen(last_name) + 1

此外,您的strncpy() 应该更好地使用分配的缓冲区的大小而不是源字符串的大小,这样您就可以避免写入超出数组的高边界。但既然你已经用过malloc(strlen(...) + 1),你可以在这里直接用strcpy()

【讨论】:

  • strncpy() 很少是正确的函数。与其他 strn*() 函数不同,它只是 strcpy() 的“更安全”版本。在某些情况下,它可以使目标数组未终止(即,不是有效的字符串);在其他情况下,它可能会浪费时间用额外的 '\0' 字符填充目标。
猜你喜欢
  • 2021-07-06
  • 2010-12-02
  • 2013-11-08
  • 2016-05-03
  • 2011-11-25
  • 2010-11-19
  • 2014-09-27
  • 2013-07-31
  • 1970-01-01
相关资源
最近更新 更多