C struct中的数组,指向常量的指针

时间:2013-09-26 12:56:10

标签: c pointers struct

我有以下代码:

typedef struct{
    char *name;
    int age;
} person;


int main(){
    person Peter = {"peter", 19};
    person Petercp = Peter;
    Peter.name[0] = 'a';
    Petercp.name = "hello";
    printf("%s %d\n", Peter.name, Peter.age);
    printf("%s %d\n", Petercp.name, Petercp.age);
}

编译器为我提供了行

的“BAD ACCESS”错误消息
Peter.name[0] = 'a'

但是以下一行似乎很好

Petercp.name = "hello";

似乎person.name的数组是指向常量的指针。我有权做出结论吗?

并且,如果我将结构中的数组声明为

char name[];

我再次被允许进行

的更改
Peter.name[0] = 'a'

为什么?

3 个答案:

答案 0 :(得分:4)

执行person Peter = {"peter", 19};时,将name指向字符串文字“peter”。

Peter.name[0] = 'a'尝试更改name所指向的1.元素。修改字符串文字是未定义的行为,在您的情况下,它会导致崩溃。在实践中,字符串文字通常被加载到内存的只读部分。

另一方面,执行Petercp.name = "hello";只是将指针更改为指向其他位置,这很好。

如果您将名称成员声明为char name[64],那么初始值设定项

  person Peter = {"peter", 19};

会将字符串“peter”复制到name数组中。 name数组只是一个普通的char数组,您可以在其中更改各个元素。

答案 1 :(得分:0)

因为你没有为peter声明任何空间,所以Peter.name [0]不存在。

当您使用常量字符串执行初始赋值时,编译器会将常量字符串值赋值给它,并且您无法更改常量。

以下方法可行:

int main(){
    person Peter;
    Peter.age = 19;
    Peter.name = calloc(sizeof(*(Peter.name)),sizeof("hello")+1);
    strncpy(Peter.name,"hello",sizeof("hello"));
    Peter.name[0] = 'a';
    printf("%s %d\n", Peter.name, Peter.age);
    free(Peter.name);
}

这里的区别在于,Peter.name = "hello"使Peter.name直接指向(const)字符串文字。 相比之下,strncpy会从该文字复制到calloc

所放置的空格

答案 2 :(得分:0)

"NAME"分配名称会创建一个字符串文字,定义为常量。 因此,您无法更改name指向的地址上的任何内容。

在c11下6.7.3

  

如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为未定义。如果尝试通过使用具有非volatile限定类型的左值来引用使用volatile限定类型定义的对象,则行为是未定义的。

Peter.name[0] = 'a'

这就是你想要在这一行中做的事情。

所以你会破坏你的代码。但幸运的是,编译器避免了这种情况。