以下是Person
的表示,
typedef struct{
const char *firstName;
const char *lastName;
}PersonDetails;
typedef struct{
const long *sinKey;
PersonDetails *value;
}Person;
其中,填充firstName
成员会产生分段错误,
int main(void){
....
Person *person = malloc(sizeof(Person));
const long key1 = 364222888L;
printf("Before key assignment\n");
person->sinKey = &key1;
printf("Before first name assignment\n");
person->value->firstName = "Sham";
printf("Before last name assignment\n");
person->value->lastName = "S";
....
}
const char *firstName
包含一个不可变的字符串。这个不可变的字符串存储在.rodata
部分中。 firstname
可以更改其指向位置。
但是,下面是输出,
$ ./pq.exe
...
Before key assignment
Before first name assignment
Segmentation fault (core dumped)
如何解决此问题?
答案 0 :(得分:10)
当你这样做时
Person *person = malloc(sizeof(Person));
您只为person
结构分配内存。您没有为person->value
分配内存。你甚至没有初始化 person->value
所以它的值将是 indeterminate ,当你取消引用它时会导致未定义的行为。
我的建议是不使用person->value
的指针,只是一个普通的结构(非指针)实例。
在不相关的注释上,请注意指针person->sinKey
,特别是如果您在实际代码中在另一个函数中创建结构。您所做的赋值将使person->sinKey
指向局部变量,一旦函数返回,该变量将超出范围。
如果你在main
函数中创建了结构,那么它是有效的,因为你所做的变量person->sinKey
指向的生命周期将是程序的生命周期。
这和上面的问题一起让我想知道你为什么这么多使用指针?指针是代码中问题的主要原因,特别是(相对)初学者。
答案 1 :(得分:2)
您必须为value
成员
person->value = malloc (sizeof(PersonDetails));
您必须检查malloc
返回值,始终
if (person->value != NULL)
{
// YOUR STUFF
}
答案 2 :(得分:2)
此:
Person *person = malloc(sizeof(Person));
还不够。
您还必须为person->值分配内存。
Person *person = malloc(sizeof(Person));
person->value = malloc(sizeof(PersonDetails));
答案 3 :(得分:0)
如果您决定使用PersonDetails *value
,则需要为此malloc()
分配一些空间。否则它只是一个不指向任何地方的悬垂指针。
正如@Some程序员老兄建议的那样,你可以简单地使用PersonDetails value
,然后你不需要任何分配,因为它不再是指针。
如果您决定使用此方法,那么您的代码将如下所示:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
const char *firstName;
const char *lastName;
}PersonDetails;
typedef struct{
const long *sinKey;
PersonDetails value;
}Person;
int main(void) {
Person *person = malloc(sizeof(Person));
const long key1 = 364222888L;
person->sinKey = &key1;
printf("%ld\n", *(person->sinKey));
person->value.firstName = "Bob";
printf("%s\n", person->value.firstName);
person->value.lastName = "Smith";
printf("%s\n", person->value.lastName);
return 0;
}
我仍然不确定你使用const long *sinKey;
的原因?这真的需要一个指针吗?