-4

Each time I execute this... I get an error:

char * var= new char[256];
var= "hola mundo\0";
delete var;

the error I get is:

malloc: *** error for object 0x10007fd20: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to

I don't want to use std::string nor std::vector... because I use in several functions char* as a parameter and I would like to be able to destroy it.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
DaWNFoRCe
  • 151
  • 2
  • 11
  • 6
    Two mistakes - `strcpy(var, "hola mundo");` instead of assign, and `delete[] var;` instead of `delete` – keltar Jun 12 '14 at 17:49
  • 5
    You should really use std::string. One reason: you can't assign strings like that. For c-style strings, you need to use `strcpy` or `strncpy` or `strcat` or `strncat`'. – Joe Jun 12 '14 at 17:50
  • "I don't want to use std::string because I use in several functions char* as a parameter" - and then? have you never heard of the `std::string::c_str()` method? – The Paramagnetic Croissant Jun 12 '14 at 17:52
  • 1
    Well, `std::string::c_str()` return value is `const char*`, it isn't allowed to be modified (even with const-cast, it will break strings internal structure like length and capacity), so it isn't always a drop-in substitute. – keltar Jun 12 '14 at 17:56
  • 1
    @keltar then `&str[0]`. That's modifiable. – The Paramagnetic Croissant Jun 12 '14 at 18:03
  • @user3477950 same as const-casted c_str, I suppose. How would you update `length()` after modifying string? – keltar Jun 13 '14 at 09:23
  • @keltar You don't update it **after** modifying it. You `resize()` it **first,** only then do you copy to it. – The Paramagnetic Croissant Jun 13 '14 at 10:06

3 Answers3

4

When you have var= "hola mundo\0"; that is assigning to a string in memory that the compiler reserves. Calling delete on that is undefined behavior. Also, there is a leak of the original var since it is never deleted. You should do something like use strcpy to copy your string into var or else use std::string so you don't have to worry about freeing it. Example: std::string var = "hola mundo";

edtheprogrammerguy
  • 5,957
  • 6
  • 28
  • 47
  • sorry man but as parametrization does not use string as a standard return datatype but char* I need to destroy what you see there... without using string.. thanks anyways! – DaWNFoRCe Jun 13 '14 at 07:56
3

The pointer value you received from new is lost when you assign something else to var. The original contents of var is gone. Then you attempt to delete the something else.

ScottMcP-MVP
  • 10,337
  • 2
  • 15
  • 15
1

Firstly, the assignment from a string literal to a char* variable does not copy the string data into the memory you allocated. Instead it simply reassigns the pointer so that var no longer points at the memory you allocated. That means the memory you allocated is lost and never properly deallocated, and it means that you're using delete with a pointer that you never allocated, which is invalid.

Secondly, you're allocating an array with new char[], so you need to use delete [] instead of just delete.

Thirdly, String literals automatically include a null terminator, so you don't need to add an extra one:

var = "hola mundo";

Lastly, if you can use C++11 or C++14 you should not be using new and delete directly. In earlier versions of C++ you can still avoid new and delete in many cases. In this case, since there's already a std::string type you should simply use that no matter what version of C++ you're using. Your three lines of code should be replaced with:

std::string var = "hola mundo";

This is simpler and safer.

bames53
  • 86,085
  • 15
  • 179
  • 244
  • Hi thanks, I forgot the [] apparently :( my bad, but as I mentioned many libraries use char* instead of string to pass values through functions that later need to be destroyed!!! So You cannot use string in those cases!! So as I said in the post.. and as is true in real life... I cannot use string... any ideas? – DaWNFoRCe Jun 13 '14 at 07:52
  • @DaWNFoRCe you can still use `std::string` both to pass `char*` data, and to manage `char*` buffers filled by the library. If you mean that you have written functions that accept `char*` and those functions need to deallocate the buffer passed in then that could present a problem for `std::string`, but it's also a bad idea for several reasons. – bames53 Jun 13 '14 at 11:59
  • Sorry but is not clear to me how I create a hole new object string type.. to destroy the one pointed by a char *. No Im not doing the later.. I'm calling functions that return char*... and then i need to destroy them that's all... – DaWNFoRCe Jun 14 '14 at 07:49
  • @DaWNFoRCe Oh, if a library is allocating the string and you have no control over the allocation then obviously you need to do whatever the library requires in order to deallocate the string. Of course that's a poorly designed library, and there are still things you can do. You should immediately hand off the allocated memory to a smart pointer. E.g `unique_ptr buf(foo());` and you may even want to immediately copy the data into a more reasonable type, such as `std::string`. E.g. `unique_ptr buf(foo()); std::string copy = &buf[0];`. – bames53 Jun 14 '14 at 16:46
  • Of course if the library is doing the allocation then the library must tell you how to properly deallocate. Asking on stackoverflow will not tell you what the library requires. The library could require `delete`, `delete[]`, `custom_library_deallocator()`, `free()`, etc. You must read the library documentation. – bames53 Jun 14 '14 at 16:48
  • Again... I don't think is the first time..and libraries when they send simple datatypes like char pointers.. well they expect you to know how to dealloc... I honestly can say I do not... how do I delete a char* pointer... easy question.. help! – DaWNFoRCe Jun 16 '14 at 10:11
  • Libraries cannot just 'expect you to know' the correct method of deallocation, because the library determines what the correct method is, and there is more than one option for them to choose. Like I said, the library might use malloc() (which means you use free(), or it might use new[] (which means you use delete[]), etc. consult the library documentation. – bames53 Jun 16 '14 at 14:02