简体   繁体   中英

Assigning (const char *) pointer type - Segmentation fault

Below is the representation for Person ,

typedef struct{

  const char *firstName;
  const char *lastName;
}PersonDetails;

typedef struct{

  const long *sinKey;
  PersonDetails *value;
}Person;

where, populating the firstName member creates segmentation fault,

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 holds an immutable string. This immutable string gets stored in .rodata section. firstname can change its pointing location.


But, below is the output,

$ ./pq.exe
...
Before key assignment
Before first name assignment
Segmentation fault (core dumped)

How to resolve this problem?

When you do

Person *person = malloc(sizeof(Person));

you only allocate memory for the person structure. You do not allocate memory for person->value . You don't even initialize person->value so its value will be indeterminate , leading to undefined behavior when you dereference it.

My recommendation is to not use a pointer for person->value , just a plain structure (non-pointer) instance.


On an unrelated note, be careful with that pointer person->sinKey , especially if you in your actual code create the structure in another function. The assignment you make will make person->sinKey to point to the local variable, which will go out of scope once the function returns.

It works if you create the structure in the main function since then the lifetime of the variable you make person->sinKey point to will be the lifetime of the program.

This, together with the above problem, leads me to wonder why you use pointers so much? Pointers are the main cause for problems in code, especially for (relative) beginners.

You must add allocation for value member

person->value = malloc (sizeof(PersonDetails));

And you must check malloc return values, always

if (person->value != NULL)
{
   // YOUR STUFF
}

This:

Person *person = malloc(sizeof(Person));

is not sufficient.

You have to allocate memory for person->value as well.

Person *person = malloc(sizeof(Person));
person->value = malloc(sizeof(PersonDetails));

If you decide to use PersonDetails *value , you need to allocate some space for this with malloc() . Otherwise its just a dangling pointer not pointing anywhere.

As @Some programmer dude suggested, you can simply use PersonDetails value , and then you don't need any allocation, as its not longer a pointer.

If you decide to use this approach, your code would then look like this:

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

I am still unsure why you use const long *sinKey; ? Does this really need to be a pointer?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM