在 C++ 上使用 malloc 的字符串数组

Array of strings with malloc on C++

由于一系列我无法控制的原因,我需要创建一个需要从 void* 指针引用的字符串数组。这个想法是遵循 C++ 中的以下模式:

void* TP = malloc(sizeof (double) * SS);
for (int i = 0; i < SS; i++) {
  ((double*) TP)[i] = IStringToDouble(Token[i]);
}

其中 Token 是一个向量,SS 是一个 int。现在,使用该模板,我虽然从以下内容开始:

void* TP = malloc(sizeof (string) * SS);
for (int i = 0; i < SS; i++) {
  ((string*) TP)[i] = Token[i];
}

我知道这是非常错误的,但是我从它开始尝试的所有修改都不起作用。

关于如何实现这一点有什么建议吗?可能吗?

我已经阅读了从 Google 或 Whosebug 找到的所有关于 C++ 字符串数组的文档,但其中 none 涵盖了从 void* 引用数组的问题。

void* TP = malloc(sizeof (string) * SS);
for (int i = 0; i < SS; i++) {
  ((string*) TP)[i] = Token[i];
}

这太可怕了,但我会忽略它并解释它为什么坏了以及如何让它工作....

malloc() 分配内存但不在其中构造任何对象。对于 string,您需要调用构造函数 - 否则新的 string 实例将包含未初始化的指针成员,string 对象将假定这些成员是指向实际文本数据的内存的指针:((string*) TP)[i] = Token[i];然后会根据这些垃圾值尝试保证容量和覆盖内存。

要解决此问题,请使用 placement-new 运算符构造每个字符串:

void* TP = malloc(sizeof (string) * SS);
for (int i = 0; i < SS; i++) {
  new (&((string*)TP)[i]) std::string(Token[i]);
}

之后您需要通过显式调用析构函数来销毁 string,然后 free() 数组。

您已经可以将任何指针转换为 void*。你不需要需要使用malloc,你不需要需要有void*指针作为唯一的指针到对象。

考虑到这一点,为什么不这样做呢?

string* TP = new string[SS];
for (int i = 0; i < SS; i++) {
    TP[i] = Token[i];
}

void *TP2 = TP;

甚至这个:

void *TP = &Token[0];

虽然,使用第二种方法,如果向Token中添加更多元素,指针将失效,并且通过该指针修改字符串将修改Token中的字符串(因为这是指针指向)。