【发布时间】:2014-05-20 19:24:40
【问题描述】:
我目前正在开发一个用 C 编写的非常基本的 shell。为此,我需要能够将输入字符串分解为“单词”,以便将其发送到 execvep()。为此,我创建了一个函数shishell(),它需要一个未知长度的字符串,并在内部创建一个字符串数组。由于事先不知道单词的大小和数量,因此字符串数组是完全动态的。
我的主要问题是,这个函数适用于字符串中的 1 或 2 个“单词”,但一旦超过 3 个“单词”,它就会开始崩溃,导致分段错误和双重免费损坏错误。
这是一个测试程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(int argc, const char *argv[])
{
shishell(argv[1]);
return 0;
}
int fakexec(char** e_input_arr) {
int c = 0;
while(*e_input_arr) {
char* x = *e_input_arr++; c++;
printf(" >%d - %s\n", c, x);
}
}
int shishell(char* e_input) {
int n = 0,
cur_i = 0,
cur_w = 0;
char tmp;
char** input = malloc(sizeof(char*));
input[n] = malloc(sizeof(char));
while ((tmp = e_input[cur_i]) == ' ') {
cur_i++;
}
while ((tmp = e_input[cur_i]) != '\0') {
switch (tmp) {
case ' ':
if (cur_i) {
if (e_input[cur_i-1] != ' ') {
n++;
input = realloc(input, (n+1) * sizeof(char));
input[n] = malloc(sizeof(char));
}
}
cur_w = 0; cur_i++;
break;
default:
input[n] = realloc(input[n], sizeof(char)*cur_w+2);
input[n][cur_w] = e_input[cur_i];
input[n][cur_w+1] = '\0';
cur_w++; cur_i++;
break;
}
printf(">%d - '%c'\n", n, tmp);
}
printf("Pre execuction\n");
fakexec(input);
printf("Post execuction\n");
int j;
for (j = 0; j < n; j++)
free(input[j]);
free(input);
}
这个程序需要一个字符串参数。
这里有一些示例输出:
% ./test test
>0 - 't'
>0 - 'e'
>0 - 's'
>0 - 't'
>1 - test
% ./test "hello world"
>0 - 'h'
>0 - 'e'
>0 - 'l'
>0 - 'l'
>0 - 'o'
>1 - ' '
>1 - 'w'
>1 - 'o'
>1 - 'r'
>1 - 'l'
>1 - 'd'
>1 - hello
>2 - world
对那些人来说一切都很好,但是:
% ./test "hello world foo"
>0 - 'h'
>0 - 'e'
>0 - 'l'
>0 - 'l'
>0 - 'o'
>1 - ' '
>1 - 'w'
>1 - 'o'
>1 - 'r'
>1 - 'l'
>1 - 'd'
>2 - ' '
>2 - 'f'
>2 - 'o'
>2 - 'o'
>1 - hello
>2 - world
>3 - foo
zsh: segmentation fault (core dumped) ./test "hello world foo"
我认为问题可能来自我对realloc、malloc 和free 的调用,但是,我并不是真的做错了什么,因为我正在根据需要进行重新定位。
【问题讨论】:
标签: c arrays string shell multidimensional-array