By bodacydo

2010-08-05 04:46:21 8 Comments

I wrote the following example program but it crashes with segfault. The problem seems to be with using malloc and std::strings in the structure.

#include <iostream>
#include <string>
#include <cstdlib>

struct example {
 std::string data;

int main() {
 example *ex = (example *)malloc(sizeof(*ex));
 ex->data = "hello world";
 std::cout << ex->data << std::endl;

I can't figure out how to make it work. Any ideas if it's even possible to use malloc() and std::strings?

Thanks, Boda Cydo.


@开机就好 2010-08-05 05:17:20

you should not use

example *ex = (example *)malloc(sizeof(*ex));

because what sizeof(*ex) return is equal to size of long or size of int, which is due to you different compile surrounding. you can use code as follow:

example *ex = (example *)malloc(sizeof(example));

@Dennis Zickefoose 2010-08-05 05:35:41

Either method of generating the size will work.

@Martin York 2010-08-05 07:48:59

Somebody will down-vote this if you are not careful (as it is wrong).

@RBerteig 2010-08-05 05:09:41

For a class or struct such as your example, the correct answer is use new not malloc() to allocate an instance. Only operator new knows how to call the constructors for the struct and its members. Your problem is caused by the string member not having ever been constructed.

However, there are rare cases where it is important that a particular patch of memory act as if it holds an instance of a class. If you really have such a case, then there is a variation of operator new that permits the location of the object to be specified. This is called a "placement new" and must be used with great care.

void *rawex = malloc(sizeof(example));  // allocate space
example ex = new(rawex) example();      // construct an example in it
ex->data = "hello world";               // use the data field, not no crash
// time passes
ex->~example();                         // call the destructor
free(rawex);                            // free the allocation

By using placement new, you are obligated to provide a region of memory of the correct size and alignment. Not providing the correct size or alignment will cause mysterious things to go wrong. Incorrect alignment is usually quicker to cause a problem but can also be mysterious.

Also, with a placement new, you are taking responsibility for calling the destructor by hand, and depending on the origin of the memory block, releasing it to its owner.

All in all, unless you already know you need a placement new, you almost certainly don't need it. It has legitimate uses, but there are obscure corners of frameworks and not everyday occurrences.

@bodacydo 2010-08-05 06:12:45

Never heard about any of this. Thanks!

@John Kugelman 2010-08-05 04:49:03

Allocating memory with malloc doesn't call any constructors. Don't mix C-style allocation with C++ objects. They don't play well together. Instead, use the new operator to allocate objects in C++ code:

example *ex = new example;

This is smarter code and will call the std::string::string() constructor to initialize the string, which will fix the segfault you're seeing. And don't forget to delete it when you're done to free the memory and call the appropriate destructors:

delete ex;

@rlbond 2010-08-05 04:49:32

The problem is that malloc does not call the constructor of example. Since a string is usually represented as a pointer on the stack, this is set to zero, and you dereference a null pointer. You need to use new instead.

@AnT 2010-08-05 04:48:52

You can't malloc a class with non-trivial constructor in C++. What you get from malloc is a block of raw memory, which does not contain a properly constructed object. Any attempts to use that memory as a "real" object will fail.

Instead of malloc-ing object, use new

example *ex = new example;

Your original code can be forced to work with malloc as well, by using the following sequence of steps: malloc raw memory first, construct the object in that raw memory second:

void *ex_raw = malloc(sizeof(example));
example *ex = new(ex_raw) example;

The form of new used above is called "placement new". However, there's no need for all this trickery in your case.

@bodacydo 2010-08-05 06:09:37

I am using malloc() because new throws exceptions rather than returns NULL. I just didn't want exceptions in that part of code. That code happens in a C callback and I don't want to throw C++ exceptions in a C callback. So I used malloc. Any thoughts about that?

@AnT 2010-08-05 06:20:19

@bodacydo: You can use new(std::nothrow) example in order to make new return null-pointer instead of throwing exceptions. You have to include header <new> to use std::nothrow constant.

@jamesdlin 2010-08-05 06:22:13

@bodacydo: If you want really new to return a null pointer on failure, use new(nothrow) example. But really you should just use try/catch to catch any thrown exception. (The std::string assignment, for example, could also throw an exception if it fails to allocate memory.)

@TheBat 2016-09-15 14:06:13

This was very useful because I'm using a library that requires me to use their custom alloc command for objects passed into their function calls, but provided no way to use it with derivations of their structs that contain non-trivial structs. Great Answer!

Related Questions

Sponsored Content

36 Answered Questions

[SOLVED] How do I check if a string contains a specific word?

60 Answered Questions

[SOLVED] How do I read / convert an InputStream into a String in Java?

3 Answered Questions

50 Answered Questions

[SOLVED] How to replace all occurrences of a string in JavaScript

82 Answered Questions

[SOLVED] How do I make the first letter of a string uppercase in JavaScript?

44 Answered Questions

[SOLVED] How do I convert a String to an int in Java?

27 Answered Questions

[SOLVED] Easiest way to convert int to string in C++

22 Answered Questions

[SOLVED] How to check if a string contains a substring in Bash

  • 2008-10-23 12:37:31
  • davidsheldon
  • 1658429 View
  • 2048 Score
  • 22 Answer
  • Tags:   string bash substring

76 Answered Questions

[SOLVED] How do I iterate over the words of a string?

  • 2008-10-25 08:58:21
  • Ashwin Nanjappa
  • 2096838 View
  • 2810 Score
  • 76 Answer
  • Tags:   c++ string split

16 Answered Questions

[SOLVED] How to check if a string "StartsWith" another string?

Sponsored Content