Reputation: 67
I find the following error in my recent implementation.
#include<iostream>
using namespace std;
void main()
{
string header="apple"
float* p = new float[10];
double*Data = NULL;
p = reinterpret_cast<float*>(reinterpret_cast<char*>(p) + header.length());
//fetch data from an another call// - it doesn't matter here as how it is returned.
for(int i=0;i<10;i++)
{
p[i] = static_cast<float>(Data[i]);
}
//publish the output to the debug window //
delete[] p; // throws _block_type_is_valid(pHead->nblockuse) crash
}
Is this is a wrong way to delete the pointer?
Thanks
Upvotes: 1
Views: 524
Reputation: 76345
The value passed to delete
or delete[]
must be a value returned by new
or new[]
, respectively:
float* p = new float[10];
// ...
delete [] p;
If the code modifies the value of p
between the new
and the delete[]
the behavior is undefined.
If you need a different pointer value based on the value of p
, do whatever you need to get it, but you must either hang on to the original value of p
or be able to recalculate it for the delete. Maybe like this:
float* p = new float[10];
float* not_p = reinterpret_cast<float*>(reinterpret_cast<char*>(p) + header.length());
// ...
delete [] p;
Upvotes: 0
Reputation: 20141
This somehow sounds like OP tries to prepare binary data consisting of a header and a sequence of float
s. To achieve this (and overcome the alignment issues mentioned by M.Salters), I would use a std::vector<char>
, resize it to the resp. full size of expected binary output, and then std::memcpy()
the contents (header and the float values) into it.
My MCVE to demonstrate this:
#include <cstring>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
int main()
{
const std::string header = "FloatData";
const float payload[] = { 1.0f, 2.0f, 3.0f };
// determine binary size of header and payload
const size_t sizeHeader = header.size();
const size_t sizeData = sizeof payload;
const size_t sizeTotal = sizeHeader + sizeData;
// prepare binary buffer
std::vector<char> buffer(sizeTotal);
std::memcpy(&buffer[0], header.data(), sizeHeader);
std::memcpy(&buffer[sizeHeader], (const char*)payload, sizeData);
// dump binary buffer
std::cout << "Buffer: " << buffer.size() << " Bytes, Dump:\n";
for (unsigned char byte : buffer) {
std::cout << ' ' << std::hex << std::setw(2) << std::setfill('0') << (unsigned)byte;
}
std::cout << '\n';
}
Output:
Buffer: 21 Bytes, Dump:
46 6c 6f 61 74 44 61 74 61 00 00 80 3f 00 00 00 40 00 00 40 40
Note:
The only reinterpret-cast left in the code is in:
std::memcpy(&buffer[sizeHeader], (const char*)payload, sizeData);
Probably for exactly such use-cases like the one of OP, there are specific exceptions made for char
(and comparable types like unsigned char
) concerning the reinterpret-casting.
From cppreference.com: reinterpret_cast conversion:
AliasedType is
std::byte
(since C++17),char
, orunsigned char
: this permits examination of the object representation of any object as an array of bytes.
Upvotes: 1
Reputation: 179907
To solve the underlying problem, you'll need a way to recover the original pointer p
. Since your header is variable-length, that means it will need to end with a length, and the floats will need to directly follow this length (with zero padding). A possible solution to achieve this zero padding could be to store the length as a float
(!). You can then get the header length as size_t(p[-1])
.
Also, in the new[]
, you'll need extra space for the header and alignment overhead.
Having said that, the far easier solution is
class Data {
std::string header;
std::vector<float> values;
};
Upvotes: 1