简体   繁体   English

无法理解为什么由于strncpy而出现细分错误

[英]Can't understand why I'm getting segmentation fault due to strncpy

I am getting a segmentation fault when I use strncpy and I cannot figure out how to fix it. 使用strncpy时出现分段错误,无法弄清楚如何解决。

Here is my rectangle.h file. 这是我的rectangle.h文件。 This is just a header file. 这只是一个头文件。

#define NAMESIZE 20

struct point {
    int x;
    int y;
};

struct rectangle {
    struct point upperleft;
    struct point lowerright;
    //char label[NAMESIZE + 1];
    char *label;
};

struct point *create_point(int x, int y);

struct rectangle *create_rectangle(struct point ul, struct point lr, 
                                   char *label);

int area1(struct rectangle r);
int area2(struct rectangle *r);
void change_label(struct rectangle *r, char *newlabel);
void broken_change_label(struct rectangle r, char * newlabel);
void print_rectangle(struct rectangle *r);

This is my rectangle.c file. 这是我的rectangle.c文件。 I am just going to show one function from it: 我只是要显示一个功能:

/* create_rectangle dynamically allocates memory to store a rectangle, gives it * initial values, and returns a pointer to the newly created rectangle. / * create_rectangle动态分配内存以存储矩形,为其提供*初始值,并返回指向新创建的矩形的指针。 */ * /

struct rectangle *create_rectangle(struct point ul, struct point lr, 
                                   char *label) {

    struct rectangle *r = malloc(sizeof(struct rectangle));
    /* TASK 1: fill in the rest of this function */
    r->upperleft = ul;
    r->lowerright = lr;
    r->label = malloc(strlen(label) * sizeof(char));
    strncpy(r->label, label, strlen(label) + 1);

    return r;
}

In the above code, I use malloc to allocate enough space for the label pointer. 在上面的代码中,我使用malloc为标签指针分配足够的空间。

When I run the tester.c program below, I get a segmentation fault error (due to the strncpy ). 当我在下面运行tester.c程序时,出现分段错误错误(由于strncpy )。

int main(void) {    

    char *str1 = "Big rectangle";
    char *str2 = "Square";

    struct point *p1 = create_point(10, 10);
    struct point *p2 = create_point(100, 100);

    struct rectangle *r1 = create_rectangle(*p1, *p2, str1);
    print_rectangle(r1);
    printf("    expecting: (10, 10) (100, 100) Big rectangle\n");

    free(p2);
    p2 = create_point(20, 20);

    struct rectangle r2;

    strncpy(r2.label, str2, NAMESIZE); //GETTING SEGMENTATION FAULT DUE TO THIS LINE
}

I suspect that I am getting a segmentation fault error because I am doing strncpy directly on r2.label . 我怀疑我收到分段错误错误,因为我直接在r2.label上执行了strncpy I suspect that because I am not allocating any space to char *label in the rectangle struct is why I am getting a segmentation fault error. 我怀疑是因为我没有在矩形结构中为char *label分配任何空间,所以我遇到了段错误。 But when I write 但是当我写

char *label = malloc(sizeof(NAMESIZE) * sizeof(char));

I get an error: 我收到一个错误:

error: expected ';' at end of declaration list` error.
strncpy(r2.label, str2, NAMESIZE);

You are trying to write to r2.label , which is a pointer that hasn't been allocated any space. 您正在尝试写入r2.label ,这是一个尚未分配任何空间的指针。

And be careful with the code that you did allocate space: 并注意分配空间的代码:

r->label = malloc(strlen(label) * sizeof(char));

strlen(label) is not enough, a string needs to be null-terminated. strlen(label)是不够的,字符串需要以空值结尾。

This code: 这段代码:

r->label = malloc(strlen(label) * sizeof(char));
strncpy(r->label, label, strlen(label) + 1);

should be: 应该:

r->label = malloc( strlen(label) + 1 );
strcpy( r->label, label );
  • You need to allocate space for the null terminator. 您需要为空终止符分配空间。
  • sizeof(char) is always 1 sizeof(char)始终为1
  • The strcpy function finishes after writing strlen(label)+1 bytes, so it is redundant to try and use strncpy . strcpy函数在写入strlen(label)+1个字节后完成,因此尝试使用strncpy是多余的。

strncpy is fairly dangerous in general because sometimes it does not output a string; 一般来说, strncpy非常危险,因为有时它不输出字符串。 my advice would be to never use it. 我的建议是永远不要使用它。

Further down, 再向下,

strncpy(r2.label, str2, NAMESIZE);

is wrong because r2.label is currently a wild pointer. 是错误的,因为r2.label当前是一个野指针。 You also need to allocate memory in the same way: 您还需要以相同的方式分配内存:

r2.label = malloc( strlen(str2) + 1 );
strcpy( r2.label, str2 );

You malloc strlen(label) bytes for the label in create_rectangle , then copy in strlen(label)+1 bytes. malloc strlen(label)字节的标签, create_rectangle ,然后在复制strlen(label)+1个字节。 Note that, if the new label you are copying in is longer, you'll overflow that allocation. 请注意,如果您要复制的新标签较长,则会使该分配溢出。 But as @YuHao points out, it doesn't matter, because you never initialized any of the fields of r2 (in particular, label ). 但是正如@YuHao指出的,这没关系,因为您从未初始化过r2任何字段(尤其是label )。

r->label = malloc(strlen(label) * sizeof(char));

您正在误分配终止字符,应该是

r->label = malloc((strlen(label)+1) * sizeof(char));

Look like, as you said, you aren't allocating any memory for your char* label . 如您所说,您看起来并没有为char* label分配任何内存。

Do: 做:

r2.label = malloc(sizeof(NAMESIZE) * sizeof(char));`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM