如何在 C++ 中动态分配 char* 变量?

How to assign char* variables dynamicly in C++?

我遇到了在program.I中将任意地址注册为char*的场景,需要将每个地址作为char*传递给第三方库以进行进一步操作。

third_party_function 在其头文件中是这样描述的:

virtual void RegisterFront(char *pszFrontAddress) = 0;

首先,程序必须从配置文件中读取一组地址,例如:

tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778; 

如果我将其定义为 cstring 并使用循环,则分析该字符串并将其分解为地址向量的过程很简单。但是每个都必须在该函数中注册,以便库在当前失败时连接到另一个地址。当前配置有 3 个地址,但应该允许任意数量的地址。

分配 char* 变量的静态方法是这样的:

...
#include third_party_lib;

char* addr1 = "tcp://18.19.20.22:7778".c_str();
char* addr2 = "tcp://18.19.20.24:7778".c_str();

RegisterFront(addr1);
RegisterFront(addr2);

我省略了从配置中分析地址的循环,但本质很清楚:我不能在程序中命名 addr[n],因为地址的数量是不确定的——这取决于有多少会写在该配置行中。

即对于 3 地址场景,我可以在代码中分配 addr1 addr2 addr3。但是一旦编译完成,如果配置行现在只包含两个地址怎么办?改成 5 怎么样?

顺便说一句:RegisterFront 函数的替换:

void printFront(char *addr){
  cout << addr <<endl;
}

假设您的配置行是这样的:

std::string s = "tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;"

s也可以是一个char*,没关系。在您的代码中的某个时刻,您已经获得了您从文件或任何地方读取的配置行的字符串表示形式。

然后为每个 URL 遍历该字符串,所有 RegisterFront 函数就是这个。

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

void trim(std::string& s) {

    size_t start = 0;
    size_t end = s.size();

    while ((start < end) && isspace(s[start]))
    {
        start++;
    }

    while ((end > start) && isspace(s[end - 1]))
    {
        end--;
    }

    s = s.substr(start, end - start);
}

void RegisterAddresses(const std::string& config_line) {

    std::istringstream ss(config_line);
    std::string address;
    while (std::getline(ss, address, ';')) {

        trim(address);

        // address[0] returns a reference to the first char in the string
        // hence, &address[0] is the char* to the front of the string
        RegisterFront(&address[0]);
    }
}

然后当您拥有 config_line(定义为 char*std::string 实例)时,您只需以任一方式调用它:

std::string s = "tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;";
RegisterAddresses(s);

这也有效(临时 std::string 传递给 RegisterAddresses - 从传入的 char* 构造)

const char* s = "tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;";
RegisterAddresses(s);