问题
For a list of reasons that I do not control, I need to create an array of strings that needs to be referenced from a void* pointer. The idea is to follow the following pattern in C++:
void* TP = malloc(sizeof (double) * SS);
for (int i = 0; i < SS; i++) {
((double*) TP)[i] = IStringToDouble(Token[i]);
}
Where Token is a vector and SS an int. Now, using that template, I though starting with something like:
void* TP = malloc(sizeof (string) * SS);
for (int i = 0; i < SS; i++) {
((string*) TP)[i] = Token[i];
}
I know that this is horribly wrong, but all the modifications I have tried starting from it don't work.
Any suggestion about how to achieve this? Is it possible?
I have gone through all the documentation about string arrays on C++ that I have found from Google or StackOverflow, but none of them covers the issue about referencing the array from a void*.
回答1:
void* TP = malloc(sizeof (string) * SS);
for (int i = 0; i < SS; i++) {
((string*) TP)[i] = Token[i];
}
This is horrible, but I'll ignore that and explain why it's broken and how to get it working....
malloc()
allocates memory but doesn't construct any objects in it. For string
, you need to invoke the constructor - otherwise the new string
instances will contain uninitialised pointer members that the string
object will assume are pointers to memory for the actual text data: ((string*) TP)[i] = Token[i];
will then try to ensure capacity and overwrite memory based on these garbage values.
To fix this, use the placement-new operator to construct each of the strings:
void* TP = malloc(sizeof (string) * SS);
for (int i = 0; i < SS; i++) {
new (&((string*)TP)[i]) std::string(Token[i]);
}
You'll need to destroy the string
s similarly afterwards by calling their destructors explicitly, and then free()
the array.
回答2:
You can convert any pointer to a void*
already. You do not need to use malloc
, and you do not need to have the void*
pointer as the only pointer to the object.
With that in mind, why not do this?
string* TP = new string[SS];
for (int i = 0; i < SS; i++) {
TP[i] = Token[i];
}
void *TP2 = TP;
or even this:
void *TP = &Token[0];
although, with the second method, the pointer will be invalidated if you add more elements to Token
, and modifying the strings through this pointer will modify the strings in Token
(since that's what the pointer's pointing to).
来源:https://stackoverflow.com/questions/28036732/array-of-strings-with-malloc-on-c