无法理解为什么我因为strncpy而出现分段错误

时间:2014-06-24 01:04:29

标签: c malloc

我使用strncpy时遇到分段错误,我无法弄清楚如何修复它。

这是我的rectangle.h文件。这只是一个头文件。

#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);

这是我的rectangle.c文件。我将展示一个函数:

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

在上面的代码中,我使用malloc为标签指针分配足够的空间。

当我运行下面的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
}

我怀疑我收到了分段错误错误,因为我正在strncpy直接执行r2.label。我怀疑,因为我没有在矩形结构中为char *label分配任何空间,这就是我得到分段错误错误的原因。但是当我写作

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

我收到错误:

error: expected ';' at end of declaration list` error.

5 个答案:

答案 0 :(得分:4)

strncpy(r2.label, str2, NAMESIZE);

您正在尝试写入r2.label,这是一个尚未分配任何空间的指针。

请注意您分配空间的代码:

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

strlen(label)是不够的,字符串需要以空值终止。

答案 1 :(得分:2)

此代码:

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

应该是:

r->label = malloc( strlen(label) + 1 );
strcpy( r->label, label );
  • 您需要为null终止符分配空间。
  • sizeof(char)始终为1
  • strcpy函数在写入strlen(label)+1个字节后结束,因此尝试使用strncpy是多余的。

strncpy一般来说相当危险,因为有时它不输出字符串;我的建议是永远不要使用它。

再往下,

strncpy(r2.label, str2, NAMESIZE);

是错误的,因为r2.label当前是一个狂野指针。您还需要以相同的方式分配内存:

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

答案 2 :(得分:0)

malloc中的标签为strlen(label) create_rectangle个字节,然后以strlen(label)+1个字节进行复制。请注意,如果要复制的新标签较长,则会溢出该分配。但正如@YuHao指出的那样,没关系,因为你从未初始化r2的任何字段(特别是label)。

答案 3 :(得分:0)

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

你正在为终止角色而分配,应该是

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

答案 4 :(得分:0)

就像你说的那样,你没有为char* label分配任何内存。

执行:

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