Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

struct containing string value causes segmentation fault upon its assignment after its creation using dynamic memory allocation

The compiler throws runtime segfault upon following code :

#include <iostream>
#include <string>
using namespace std;

struct Node{
  int data;
  void *next;   
  string nodeType;
};

Node* initNode(int data){
  Node *n = (Node*)malloc(sizeof(Node));
  n->data = data;
  n->next = NULL;
  n->nodeType = "Node";   //if this line is commented it works else segfault
  return n;
}

int main() {
  Node *n1 = initNode(10);
  cout << n1->data << endl;
}

Can someone please explain why string assignment does not work inside a struct which is dynamically allocated where in case of static allocation why it works ?

where as the following way it works :

Node initNode(string data){
  Node n;
  n.data = data;  //This works for node creation statically
  n.next = NULL;
  n.nodeType = "Node";  //and even this works for node creation statically
  return n;
}

and then in the main function:

int main() {
  Node n2 = initNode("Hello");
  cout << n2.data << endl;
}
like image 448
Dhwanit Avatar asked Mar 17 '15 09:03

Dhwanit


3 Answers

This doesn't work because you don't actually construct a Node instance into the memory which you malloc.

You should use new instead:

Node *n = new Node{};

malloc only allocates memory, it has no idea what a class is or how to instantiate one. You should generally not use it in C++.

new allocates memory and constructs an instance of the class.

like image 107
TartanLlama Avatar answered Sep 24 '22 21:09

TartanLlama


There is no place, where std::string constructor is executed.

You should use new

example *e = new example;

or placement new

void *example_raw = malloc(sizeof(example));
example *e = new(example_raw) example;
like image 25
senfen Avatar answered Sep 22 '22 21:09

senfen


 Node *n = (Node*)malloc(sizeof(Node));

This cast is nonsense. You can't just tell the compiler to pretend that a chunk of data you just allocate contains a valid Node object and then manipulate it.

like image 30
David Schwartz Avatar answered Sep 23 '22 21:09

David Schwartz