我正在创建一个函数,根据目标(可以是“”,“a”等)将char *拆分为其他char *的数组。在这个例子中,我使用一个空格(“”)将我的char *拆分成一个char *数组。
但是,我在处理动态分配的内存时遇到了一些困难。我为char *数组分配了内存,我将作为split函数返回值返回,另一个用于复制我从主char *参数中读取的每个分离的const *。
#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;
}
我发现当使用'delete [] n_cstring'时,不是单独输出char *(比如“I”“love”“Thanos”),而是输出“love”“love”“Thanos” ”。每个例子都在做这种重复。为什么'删除'这样做?
另外,当我返回一个动态分配的数组('sa')时,你会建议我删除它吗? - 主要功能无法识别'sa'。
答案 0 :(得分:1)
一个问题是您要过早删除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>
。这将使您免于分配和删除字符数组,自动修复潜在的崩溃。