3

I am a java programmer and one day old to C/C++ programming. And I am attempting to create a std::string from char*

This is my character buffer -

char* token = (char*) malloc ((numberOfCharacters) * sizeof (char));

And this is how I create a std::string object -

std::string strKey (token); 

But do I need to free 'token' after this call or the strKey refers to character buffer pointed by token?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Mayur
  • 75
  • 1
  • 10
  • why do you allocate char array with malloc anyway? stack allocate it. – David Haim Jun 09 '15 at 13:23
  • 6
    There is no such thing as "C/C++ programming". C and C++ are not compatible. Pick one language. It is generally a very bad idea to use malloc in C++ programs. – Lundin Jun 09 '15 at 13:24
  • @DavidHaim `numberOfCharacters` is not a constant (VLAs are not available in C++)? Existing code that cannot be changed? – Stefano Sanfilippo Jun 09 '15 at 13:25
  • For C, `void *` (as is the result of `malloc()` & friends) should not be cast. Also, do not take `sizeof(char)`, this will never differ from 1 as it defined by the standard as such. Finally: as Lundin comments, C and C++ are different languages. – too honest for this site Jun 09 '15 at 13:26
  • @StefanoSanfilippo: I undestand the first line i C, where VLAs are optional since C11. Another reason to just pick one language. – too honest for this site Jun 09 '15 at 13:28
  • Since you're using `std::string`, I'll ignore C and comment on C++. Have you considered using `std::vector` as your character buffer? This will manage the allocation and deallocation of memory for you. You could also use `std::string` directly as your character buffer, however this will mean that the `size()` reported would be the size of the character buffer, and not necessarily the size of the "string" contained within it. – Andrew Jun 09 '15 at 13:29
  • IIRC, mxy comment about `sizeof(char)` applies for C++, too. – too honest for this site Jun 09 '15 at 13:30
  • C++ does not have a gabage collection as Java, Python, etc. So, yes, you have to delete/free an object once not required anymore in general. – too honest for this site Jun 09 '15 at 13:32
  • @Olaf, (In my opinion) writing `sizeof(char)` isn't particularly bad. It's evaluated at compile-time, yielding `1`. The compiler should then optimise away the useless `* 1` multiplication, and nobody is any the worse off. If, for any reason, the type is changed from `char` somewhere down the line, the presence of `sizeof(char)` may remind the maintainer that they need this multiplication now. – Andrew Jun 09 '15 at 13:33
  • I wanted to do some parsing on the string and unfortunately the module compiles with VS2005 which does not have regular expression library (it comes with VS2010) . I had no option but to perform raw pointer arithmetic. Thats where malloc comes in picture; to create a char buffer perform parsing create tokens (again malloc) and finally pass on std::strings to the caller. – Mayur Jun 09 '15 at 13:35
  • 2
    @Mayur it sounds like you can do all of that using `std::string` alone. Perhaps you'd be better off posting a question about what you're trying to achieve, instead of one about a technical stumbling block you encountered on your way to "the wrong" solution? By all means show your working, i.e. the solution you've already got. It'll encourage people to help you think about improvements, rather than dismissing your question as "write my code for me please?" – Andrew Jun 09 '15 at 13:37
  • I need consume a string of following format -key1:value1|key2:value2|key3:value3 and pass on array of token object , where token object defined as {std::string key, std::string value}. I could not find any thing for double parsing : first tokenizing on '|' and then ':' other than doing character by charcter parsing with help of pointer aritmatic. – Mayur Jun 09 '15 at 13:43
  • @Andrew: I normally avoid this by alway taking the `sizeof()` the type I assign to: `char *c = malloc(sizeof *c);`. This avoids forgetting to edit if I change the type lateron. However, If one does not know he has to multiply by `sizeof(type)`, she should not use `malloc()` at all (and here it is definitively the wrong way). – too honest for this site Jun 09 '15 at 13:43
  • @Olaf, you make a good point :) – Andrew Jun 09 '15 at 13:45
  • @Mayur there are countless examples of string tokenisers that use `std::string` to do exactly that, without any requirement for manual memory management. Use your favourite search engine to find one. – Andrew Jun 09 '15 at 13:46
  • 1
    @Andrew: Good programmers are lazy programmers (not bijective:-). – too honest for this site Jun 09 '15 at 13:46
  • 1
    @Mayur, before you go any further trying to write C++ code, get a good C++ book, and read it. A number of good recommendation can be found here: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list?lq=1 What you're trying to do is really not that hard using only std::string, but you need to learn how to use C++ & the standard containers first. – Rob K Jun 09 '15 at 13:58

3 Answers3

6

std::string constructor makes a copy of token, it doesn't take ownership of it. So yes, you have to free() it after building strKey.

Anyway, you should use new and delete operators in C++ code:

char *token = new char[numberOfCharacters];

//...

std::string strKey(token);
delete[] token;

//...

Don't use C malloc and free, unless you have a specific reason for doing so.

Stefano Sanfilippo
  • 32,265
  • 7
  • 79
  • 80
3

If you don't plan on using token anymore, yes, you have to free it. String's constructor can't magically guess that you want to free it.

You should also check to make sure that malloc() succeeded; malloc() returns NULL to indicate an error condition.

Also, sizeof(char) is always 1.

Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70
3

If you have a malloc, you need a free. The freecould be managed by an another object (see Stefano comment) if you pass it the pointer. But here, since you are managing the pointer by yourself, you must free it when you do not need it anymore.

And in c++, you should not use malloc if you are not forced to do it, malloc is more a C thing.

Bastien
  • 994
  • 11
  • 25
  • 2
    This correct, but a bit to general to answer the OP's **specific** question. I did not downvote btw ... – alk Jun 09 '15 at 13:26
  • 1
    Not the most detailed answer, but actually there is nothing general about it. Its right on the central issue asked about without all the superfluous trim. – ryyker Jun 09 '15 at 13:30
  • 1
    @ryyker this is certainly true, but it doesn't detail _who_ performs a free. If `std::string` took ownership of the pointer, then a `delete` would be performed by its destructor, not by directly the user. Freeing `token` is such a situation will lead to a double free error. – Stefano Sanfilippo Jun 09 '15 at 13:31