简体   繁体   中英

Calling new [] and delete [] in different compiler versions

Facilitating a framework that only runs under old compiler versions, I'm forced to design an interface for my dynamically linked library, that works across different compiler versions. I came up with this code for returning a character string:

char * returnCharStr() {
  ...
  auto ret = new char[ str.length ];
  ... // copy string data into ret
  return ret;
}

Now, to avoid a memory leak, I have to invoke delete [] on the returned character string at some point (in the code compiled by another compiler version):

...
auto cstr = returnString();
... // work with cstr
delete [] cstr;

This code crashes at runtime. The solution is to call delete [] inside of a function that is compiled into the dynamic library (where the returnCharStr() function resides). The question is, why does the code crash on the delete [] statement?

Memory allocated with one framework must be freed by that same framework, especially when that memory is passed around between different environments, different compilers, etc. You don't have control over what the caller does with the memory, and the caller has no concept how the memory was allocated so it can't free it directly.

To do what you are attempting, you must expose another function to free the memory correctly, eg:

char * returnCharStr() {
    ...
    char* ret = new char[ str.length ];
    // copy string data into ret...
    return ret;
}

void freeCharStr(char *str) {
    delete[] str;
}

char* cstr = returnString();
// work with cstr...
freeCharStr(cstr);

I have not had problems like that between versions of the compilers because the way the memory gets allocated has not changed much over time.

However, there are compilation flags that are definitely not compatible between each others such as the /MT and /MTd . These make use of different types of allocators and deallocators (the debug version adds padding buffers to check whether you have a "simple" buffer overflow and generate errors when such are detected.)

If you do not know how the existing binary was compiled, it's going to be difficult to guess, although I think there is a way to look at the binary, I don't really know what to look at. That could be the subject of another stackoverflow question, though.

If you have control over the compilation of both binaries, then just make sure you use the same flags. If you don't try them all in your new binary to see which one works... I would imagine it would be the one without the d (debug) so you may have to test with or without multithread turned on.

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