复制到新阵列时出现动态内存分配问题

Dynamic memory allocation issue when copying to new array

本文关键字:动态 内存 问题 分配 新阵列 阵列 复制      更新时间:2023-10-16

我正在创建一个函数,根据目标(可以是" ","a"等(将char *拆分为其他字符*数组。在这个例子中,我使用空格 (" "( 将我的字符 * 拆分为一个字符 * 数组。

但是,我在处理动态分配的内存时遇到了一些困难。我为我将作为拆分函数返回值返回的 char * 数组分配了内存,以及另一个用于复制我从主 char * 参数读取的每个分隔的常量 *

的内存。
#define MAX_SIZE 65535
#define MAX_SPLIT_SIZE 1023
char** a_split(char * x, const char * target, int sn){
    char ** sa = nullptr;
    size_t t_len = strnlen(target, MAX_SIZE);
    if(t_len < 1 || t_len > MAX_SIZE){ return sa; }
    int split_num = 0;
    if(sn > 1 && sn < MAX_SPLIT_SIZE){
        sa = new char * [sn + 1]();
        split_num = sn;

    }else if(sn == -1){
        sa = new char * [MAX_SPLIT_SIZE + 1];
        split_num = MAX_SPLIT_SIZE;
    }else {
        return sa;
    }
    char * ptr = x;
    char * mi;                                              // Match index.
    int i = 0;                                              // Index of 'sa' array.
    while((mi = std::strstr(ptr, target)) && split_num--){
        size_t dif = mi - ptr;
        char * n_cstring = new char[dif + 1]();
        memcpy(n_cstring, ptr, dif);                        // Copying content to new string.
        sa[i++] = n_cstring;                                // Append new string to 'sa' array of split strings.
        ptr += dif;
        ptr += t_len;
        delete [] n_cstring; // <------- This is causing some weird errors.
    }
    if(mi == nullptr){
        sa[i] = ptr;
    }
    return sa;
}
int main(int argc, char * argv[]){
    char  c[] = "I love Thanos";
    char ** x = a_split(c, " ", -1);
    for(int i = 0; x[i]; i++){
        puts(x[i]);
    }
    return 0;
}

我发现当使用"删除[]n_cstring"时,它不是单独输出字符*(如"我"爱"灭霸"(,而是输出"爱"爱"灭霸"。它对每一个例子都进行这种重复。为什么要"删除"这样做?

另外,由于我返回一个动态分配的数组('sa'(,你会建议我在哪里删除它? - 主函数无法识别"sa"。

一个问题是你删除n_cstring太早了:因为你把它存储在数组sa[],即

sa[i++] = n_cstring;

在循环中立即删除它会使sa[i]挂起。最终结果是,您的main除了由于从不删除sa而导致内存泄漏外,还将具有未定义的行为。

我正在返回一个动态分配的数组(sa(,您会建议我在哪里删除它?

只有一个地方可以做到这一点 - 它是main.您将sa放入x,因此您需要在完成打印后调用delete[] x

请注意,由于必须从函数中删除delete[] n_cstring a_split因此main还必须在删除x本身之前删除x的各个元素。

到目前为止,最好的方法是更改代码以使用 std::vector<std::string> .这将使您免于分配和删除字符数组,自动修复潜在的崩溃。