我有一个C ++函数,它在遇到分隔符时将char数组拆分为多个char数组。出于某种原因,当保存第三个拆分数组时,程序崩溃,有时会返回std :: bad_alloc异常。
char ** explode(const char * arr, const char delim) {
int start, end, curr=0, count=1;
char ** strings;
//Iegūst explodēto stringu skaitu
for (int i = 0; arr[i] != 0; i++) {
if (arr[i] == delim && i != 0 && arr[i+1] != 0 && arr[i+1] != delim ) { //Nav pirmais, nav pēdējais, nav pa labi vēlviens delimiters
count++;
}
}
strings = new char*[count];
start = 0;
for (int i = 0; arr[i] != 0; i++) {
if (arr[i] == delim || arr[i+1] == 0) {
if (arr[i] == delim) {
end = i;
} else {
end = i+1;
}
if (end-start < 1) {
start++;
} else {
copystring(arr,strings[curr++],start,end-start);
start = i+1;
}
}
}
for (int i = 0; i < count; i++) {
cout << strings[i] << endl;
}
return strings;
}
//Pārkopē daļu no pirmā char masīva uz otru, no START pozīcijas, līdz GARUMS garumā
void copystring(const char * from, char *& to, const int start, const int garums) {
int curr=0;
if (garums < 1 || start > charlen(from)) {
return;
}
to = new char[garums];
for (int i = start; i < start+garums && from[i] != 0; i++) {
to[curr++] = from[i];
}
to[curr] = 0;
}
很难说,因为它并没有真正告诉我哪一行出了问题,但我认为它发生在
to = new char[garums];
我已尝试在CodeBlocks中调试此行,但出于某种原因,在使用断点和跟踪变量时,应用程序正常工作并正确执行。它只在正常运行时崩溃,无需调试......
另请注意,除了fstream和iostream之外,我不能使用字符串或几乎任何库。
编辑:我尝试将new char[garums]
部分更改为new char[100]
,然后神奇地开始工作。问题是我然后将其更改为new char[10]
,在这种情况下,一切仍然有效。我甚至将保存的文本输出到控制台,它保存了所有内容。怎么能在10个字符长的字符数组中保存大字(我测试的单词超过10个字符)?当我将其更改为new char[1]
时,它再次开始崩溃,但仅在第3次循环迭代后再次崩溃。所以它以某种方式保存了1个字符长数组中的前2个单词?
EDIT2:现在它甚至神奇地开始使用new char[garums]
。这里有什么不对,有人有什么想法吗?
答案 0 :(得分:0)
由于我不知道你有什么输入数据,我将不得不猜测:
这里你分配你的指针数组,但请注意所有的指针都是未初始化的。
strings = new char*[count]
然后当您解析代码时,使用变量curr,您可以自由运行,因此不确定所有字符串[]是否已设置为某个值,或者curr是否落在大于count的数字上。
如果我是你,我会检查以确保
a)curr不超过计数
b)如果curr落在小于count的值上,则将其余的指针设置为nullptr。
答案 1 :(得分:0)
在您尝试使用指针时,您在问题中提到的错误可能会突然出现 指针从爆炸函数返回。 一些指针;如果你必须编写C代码,不要使用C / C ++的混搭, 使用库函数而不是重新发明轮子(在copystring中strncpy) 你的单词计数已关闭,因为你没有考虑到之间的单词 最后一个分隔符和EOL 以下是对代码的一些细微更改,作为完整的示例:
#include <stdio.h>
#include <strings.h>
void copystring(const char *from, char **to, const int numchars)
{
if (numchars > 0) {
*to = new char[numchars];
strncpy(*to, from, numchars) ;
(*to)[numchars] = '\0' ;
}
}
char **explode(const char * buffer, const char delim)
{
int count = 0 ;
if (strlen(buffer) > 0) {
int inword = 0 ;
int idx = 0 ;
do {
if (buffer[idx] == delim || buffer[idx] == '\0') {
if (inword == 1) {
count++ ;
inword = 0 ;
}
} else {
inword = 1 ;
}
} while (buffer[idx++] != 0) ;
}
int start = 0;
int end = 0 ;
int curr = 0 ;
int idx = 0 ;
char **values = new char*[count+1];
do {
if (buffer[idx] == delim || buffer[idx] == '\0') {
end = idx;
if (end-start > 0) {
copystring(&buffer[start], &values[curr++], end - start) ;
}
start = ++end ;
}
} while (buffer[idx++] != 0) ;
values[curr] = NULL ;
for (int idx = 0; idx < count; idx++) {
fprintf(stdout, "'%s'\n", values[idx]) ;
}
return values;
}
int main(int argc, char *argv[])
{
char inputstr[] = "The, quick, brown, fox, jumped, over,,, ,,, ,,,,, ,,,, the, lazy, dog's, back" ;
char **values = explode(inputstr, ',') ;
while (*values != NULL) {
fprintf(stdout, "%s\n" , *values) ;
*values++ ;
}
return (0) ;
}
答案 2 :(得分:-1)
这可能与to
类型为char*&
而非类型char*
有关。
另一方面,我从来没有像这样编写C ++(你确定这不是C吗?)。使用显式内存管理(如“新”)与玩俄语轮盘赌一样好。
这是一种更标准的C ++方式:
#include <vector>
#include <string>
#include <iostream>
std::vector<std::string> splitString(std::string& str, char c) {
std::vector<std::string> substrings;
while(true) {
unsigned pos = str.find(c);
substrings.push_back(str.substr(0,pos));
if(pos == std::string::npos) break;
str = str.substr(pos+1);
}
return substrings;
}
int main()
{
char c = '*';
std::string str = "Some*string*that we need to split*properly*";
std::vector<std::string> result = splitString(str,c);
for(unsigned i = 0; i < result.size(); ++i) {
std::cout << i << ": " << result[i] << "\n";
}
}
输出:
0: Some
1: string
2: that we need to split
3: properly
4: