分配(const char *)指针类型 - 分段错误

时间:2017-01-23 08:05:02

标签: c struct

以下是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)

如何解决此问题?

4 个答案:

答案 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;的原因?这真的需要一个指针吗?