strncpy只复制字符串的一部分

时间:2015-01-24 13:48:45

标签: c string strncpy

假设我有这样的结构

typedef struct _student {
    int studentID;
    char name[30];
    char class[10];
    char department[10];
} Student;

并且以下函数创建Student类型的新变量:

Student *new_student(int id, char *name, char *class, char *dept) {
    Student *s = (Student *)malloc(sizeof(Student *));

    s->studentID = id;
    strncpy(s->name, name, sizeof(s->name) - 1);
    s->name[sizeof(s->name) - 1] = '\0';
    strncpy(s->class, class, sizeof(s->class) - 1);
    s->class[sizeof(s->class) - 1] = '\0';
    strncpy(s->department, dept, sizeof(s->department) - 1);
    s->department[sizeof(s->department) - 1] = '\0';
    return s;
}

void display_student(Student *s) {
    printf("Student: %d | %s | %s | %s\n", s->studentID, s->name, s->class, s->department);
}

要测试我的代码,我只需在main()

中编写一些简单的东西
int main() {

    Student *s1 = new_student(20111201, "Lurther King Anders Something", "ICT-56", "SoICT");
    Student *s2 = new_student(20111202, "Harry Potter", "ICT-56", "SoICT");
    Student *s3 = new_student(20111203, "Hermione Granger", "ICT-56", "SoICT");
    Student *s4 = new_student(20111204, "Ron Weasley", "ICT-56", "SoICT");
    display_student(s1);
    display_student(s2);
    display_student(s3);
    display_student(s4);

    return 0;
}

但是,结果出乎意料并且很奇怪:

Erro

有人可以为我解释为什么这个奇怪的结果!我认为我是以正确的方式做事的,我已经应用了strncpy的安全使用,但我没有'理解输出。

3 个答案:

答案 0 :(得分:4)

 ... malloc(sizeof(Student *));

分配

sizeof(Student *)

字节。通常为4或8,因为Student *是指针类型。

你可能想要

     ... malloc(sizeof(Student));

ov甚至更好:

Student * s = malloc(sizeof(*s));

甚至没有无用的括号:

Student * s = malloc(sizeof *s); /* sizeof is an operator, not a function. */

malloc(sizeof *s)读取为:“分配与s所指向的字节数相同的字节数。

答案 1 :(得分:2)

Student *s = (Student *)malloc(sizeof(Student *));

那条线是错的。您可以为Student分配要用于的内存,但只需要Student*

通过将表达式而不是类型传递给sizeof,您可以更不可能发生此类错误 另外,in C you don't cast on assigning from a void* to an other data-pointer-type

Student *s = malloc(sizeof *s);

作为建议,如果需要自己定义,请考虑使用strlcpy 当然,除非您依赖于将剩余的缓冲区归零,例如因为您将它们直接写入文件 strncpy几乎总是错的,尽管你似乎已经巧妙地避免了所有陷阱(可能的例外情况除外)。

答案 2 :(得分:-1)

好的,首先: malloc(sizeof(Student *))你只有4个字节的指针大小,所以你的结构没有足够的内存。我想知道它是如何实际工作的,但无论如何。因此,要获得结构的大小,请使用以下示例:

  

学生* s =(学生*)malloc(sizeof(学生));

在您尝试执行以后,您在堆中分配了新的数据:

  

strncpy(s-> name,name,sizeof(s-> name) - 1);

这里你的 s->名称在内存中有一些垃圾,因为你没有为这个内存分配任何数据,你应该使用函数参数中的数据长度

 Student *new_student(int id, char *name, char *classSt, char *dept) 
{
    Student *s = (Student *)malloc(sizeof(Student));

    s->studentID = id;

    strncpy(s->name, name, strlen(name) + 1);
    strncpy(s->classSt, classSt, strlen(classSt) + 1);
    strncpy(s->department, dept, strlen(dept) + 1);

    return s;
}