C - strncpy用法 - 段错误

时间:2016-07-05 08:19:25

标签: c strncpy

char *test={"0x11","0x12","0x13","0x00","0x00"};
void change(char* test1, char* test2){
     strncpy(test[3], test1, 4);
     strncpy(test[4], test2, 4);
}

chage("0x55","0x66");

我可以直接将字符分配给数组元素。但是,它会导致内存泄漏。这就是我使用strncpy()的原因。

请告知您是否知道如何解决问题。

2 个答案:

答案 0 :(得分:4)

至少有三个你可以在这里获得段错误(一个建议是启用编译器警告 - 他们经常选择"愚蠢的错误")。

问题是test可能是误报,应该是:

char *test[]={"0x11","0x12","0x13","0x00","0x00"};

使用char*数组初始化char*,这意味着您使用该数组中的第一个指针初始化test - 这意味着test将指向字符串文字"0x11",因此当您使用test[3]作为strncpy的参数时,您将发送1转换为指针(可能是地址0x31)。然后strncpy会尝试写入最不可能允许的地址。你在这里有近四分之一的理由,如果你曾使用test[5],你会被要求访问超出字符串末尾的内容(你可以访问test[4],因为它是终止空值字符串)。

即使您修复了这些问题,也会出现问题,因为test[3]test[4]是使用字符串文字进行初始化的。然后strncpy将尝试修改未定义行为的字符串文字 - 段错误是因为test[3]test[4]驻留在只读内存中(允许它们位于只读内存中)修改字符串文字的一个原因是未定义的行为)。

你可以做的是确保你在test中有可写副本,这可能不是C中的直接副本。一个正常的解决方案是拥有一个功能(你必须手动调用)设置test,并将其撕下来:

void init_test(void) {
    int j;

    for(j=0; j<sizeof(test)/sizeof(test[0]); j++)
        test[j] = strdup(test[j]);

}

void init_fini(void) {
    int j;

    for(j=0; j<sizeof(test)/sizeof(test[0]); j++)
        free(test[j]);
}

答案 1 :(得分:0)

另一个答案给出了一个很好的理由(从不尝试修改字符串的内容(str(n)cpy会这样做))。

我甚至不确定你想将“字符”表示为字符串,尤其是因为第一个声明不能正常工作(将字符串数组分配给字符串)。

确定这需要做很多工作,但是你应该首先将'0x11'替换为'\ x11'(IE实际上使用字符),仅仅通过赋值替换strncpy(真正的字符是原子类型,可以直接分配)并最终更改更改函数的参数以获取字符而不是字符串。