首页 > 解决方案 > 将 c++ 向量转换为 char ** 而不会发生内存泄漏

问题描述

我正在尝试将字符串向量转换为 char ** 以传递给另一个创建 hostent 结构的方法。我一直试图弄清楚这一点,但不知道该怎么做。这就是我正在做的

#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <netdb.h>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

static struct hostent host;

#define INADDRSZ 4
#define _UNCONST(a) ((void *)(unsigned long)(const void *)(a))

void tokenize(string const &str, const char delim, vector<std::string> &out) {
    size_t start;
    size_t end = 0;

    while ((start = str.find_first_not_of(delim, end)) != std::string::npos){
        end = str.find(delim, start);
        out.push_back(str.substr(start, end - start));
    }
}

static struct hostent * mk_hostent (const char *name, char **aliases, char **haddress, int addrsz, int af) {
    host.h_name = const_cast<char*> (name);
    host.h_addr_list = haddress;
    host.h_aliases = aliases;
    //host.h_addr_list[index] = (char *)_UNCONST(&host_addr[index]);
    host.h_length = addrsz;
    host.h_addrtype = af;
    //host.h_aliases = _UNCONST(aliases);
    return (&host);
}

void getHostAddrList (string hostname, vector<string> ipsAndHost, vector<string> &addrs) {
    cout << "I reached here" << "\n";
    vector<string> tokens;
    for (int i = 0; i < ipsAndHost.size(); i++) {
        tokenize(ipsAndHost[i], ' ', tokens);
        // comparing if hostname same then pushing ip to host addrs list
        if (hostname.compare(tokens[1]) == 0) {
            addrs.push_back(tokens[0]);
        }
        tokens.clear();
    }
}

void getAliasList (string hostip, vector<string> ipsAndHost, vector<string> &aliases) {
    vector<string> tokens;
    for (int i = 0; i < ipsAndHost.size(); i++) {
        tokenize(ipsAndHost[i], ' ', tokens);
        // comparing if host ip same then pushing host alias to aliases list
        if (hostip.compare(tokens[0]) == 0) {
            aliases.push_back(tokens[1]);
        }
        tokens.clear();
    }
}


char ** vector2string (vector<string> &input) {
    char ** arr = new char*[input.size()];
    for(size_t i = 0; i < input.size(); i++){
        arr[i] = new char[input[i].size() + 1];
        strcpy(arr[i], input[i].c_str());
    }
    return arr;
}

static struct hostent * gethostbyaddr_iri (const char *addr, int af) {
//void printLines(const char * addr){
    fstream file("sampleFile");
    string line;
    vector<string> readLines;

    while (getline(file, line)) {
        // skipping empty line
            if (line.empty()) {
                continue;
            }
        // skipping comments
        if (line[0] == '#') {
            continue;
        }

        readLines.push_back(line);

    }

    vector<string> ips;
    vector<string> hostAddresses;
    vector<string> hostAliases;

    for (int i = 0; i < readLines.size(); i++) {
        tokenize(readLines[i], ' ', ips);
        //ips[0] will have ip address to compare
        if (strcmp(ips[0].c_str(), addr) == 0) {
            cout << "one was same" << "\n";
            getHostAddrList(ips[1], readLines, hostAddresses);
            getAliasList(ips[0], readLines, hostAliases);
            //return mk_hostent(ips[1],
        }
        // clearing vector for next loop
        ips.clear();

        char ** hAddr = vector2string(hostAddresses);
        char ** hAlias = vector2string(hostAliases);

        return mk_hostent(ips[1].c_str(), hAlias, hAddr, INADDRSZ, AF_INET);
    }

}

int main() {
    gethostbyaddr_iri("128.0.0.16", 2);
}

因此,如果您看到我调用 vector2string 方法将向量字符串转换为 char **,然后将其传递给 mk_hostent 方法。内存永远不会被释放,我需要一种方法将我的向量转换为 char ** 而不会导致内存泄漏

标签: c++

解决方案


您只需要一个数组char*来保存各种字符串的地址。为避免内存泄漏,您可以使用std::vector<char*>指向字符串向量,如下所示:

std::vector<char*> vector2string (std::vector<string>& input) {

    std::vector<char*> arr;

    for(auto& s: input)
        arr.push_back(&s[0]); // add the address of each string array

    return arr;
}

并像这样使用它:

std::vector<char*> hAddr = vector2string(hostAddresses);
std::vector<char*> hAlias = vector2string(hostAliases);

hostent host = mk_hostent(ips[1].c_str(), hAlias.data(), hAddr.data(), INADDRSZ, AF_INET);

确保hAddr和在&hAlias分别更改未使用 ,因为它们指向实时数据。对于具有指向其数据的指针的返回对象也是如此。 hostAddresseshostAliaseshost


推荐阅读