我正在尝试编写一个函数,将char**数学表达式分解为其组成部分。例如:"(10 - 2)/2"将变成{(,10,-,2,),/,2}。
由于我给出的问题描述,返回类型必须是char**(指向字符指针的指针,但本质上是字符串数组)。我是C/++的初学者,所以我对指针和内存管理相当不熟悉。
char* intTocharStar(int x) {
int length = snprintf( NULL, 0, "%d", x );
char* str = (char*)malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
return str;
}
char* convertChar(char c) {
char* pointer = (char*)malloc(2*sizeof(char));
pointer[0] = c;
pointer[1] = ' ';
return pointer;
}
char **tokenize(const char* input) {
char **arr = (char**)malloc(1024 * sizeof(char*));
char op;
int num;
int index = 0;
stringstream parser(input);
while (parser) {
if (isalnum(parser.peek())) {
parser >> num;
cout << "Num " << num << 'n';
//args[index] = intTocharStar(num);
strcpy(arr[index], intTocharStar(num));
} else {
parser >> op;
cout << "Op " << op << 'n';
//args[index] = convertChar(op);
strcpy(arr[index], convertChar(num));
}
index++;
}
char** res = (char **)malloc(100 * sizeof(char*));
// remove final element, which is a duplicate
for (int i = 0; i < index - 1; i++)
res[i] = arr[i];
free(arr);
return res;
}
当我运行这段代码时,程序在for循环第一次运行时突然停止。我决定试着调试这个程序,并在这一行得到了一个分段错误:
arr[index] = intTocharStar(num);
在这里,从输入解析出来的int将作为char**添加到输出char**中。在阅读了这里之后,我尝试将其更改为:
strcpy(arr[index], intTocharStar(num));
但我仍然得到相同的分割错误。我还写了一个简短的程序,其中一个char*在main函数中被简单地格式化为char**的第一个索引,并得到了相同的分段错误,所以我认为问题要么是访问arr的那行,要么是声明它的这行:
char **arr = (char**)malloc(1024 * sizeof(char*));
然而,从我所读到的,这似乎是声明指针和分配内存的标准方式。有什么我监督或有一种方法来进一步调试这个?
这里有几个你会犯的大错误,但我只解释一个可能会解决你所有内存问题的错误。
char **arr = (char**)malloc(1024 * sizeof(char*));
你想分配一个char类型的矩阵,而你真正做的是分配一个指向char类型指针的指针数组。这意味着你将分配1024*8个指针(如果这是64位编译器)指向char的指针。您没有为1024个字符串分配足够的空间,而是为指针分配了空间。更好的方法是分配一个字符串数组:
char** arr= new char*[1024];
对于每个字符串你应该分配内存。例如:
arr[0] = new char[20];
当然,最后你应该释放你分配的每个字符串和arr变量。
delete arr[0]; //delete one string
delete[] arr; // delete arr char**
一般来说,你最好将它转换为字符串数组,并使用字符串而不是char**(这将解决你需要管理内存的问题)。