Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中清除此数组指针?_C_Arrays_Pointers - Fatal编程技术网

如何在C中清除此数组指针?

如何在C中清除此数组指针?,c,arrays,pointers,C,Arrays,Pointers,我正在尝试使用系统调用来完成一个基本的bash,但是我在使用指针数组时遇到了一些小问题 为了恢复代码,我使用read()将命令从stdin读入缓冲区,然后使用strep()将命令与参数分离,并将所有参数放入一个数组中。然后我用fork()创建一个新进程,并用execvp()的相关参数执行该命令 所有这些都进入一个无限循环,直到用户键入“quit”(尚未编码)。问题是在第一次迭代之后,对于下一个命令和参数,我需要*pArgs为空。我不知道怎么做 这是我的密码: #include <stdio

我正在尝试使用系统调用来完成一个基本的bash,但是我在使用指针数组时遇到了一些小问题

为了恢复代码,我使用read()将命令从stdin读入缓冲区,然后使用strep()将命令与参数分离,并将所有参数放入一个数组中。然后我用fork()创建一个新进程,并用execvp()的相关参数执行该命令

所有这些都进入一个无限循环,直到用户键入“quit”(尚未编码)。问题是在第一次迭代之后,对于下一个命令和参数,我需要*pArgs为空。我不知道怎么做

这是我的密码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv) {
    char bBuffer[BUFSIZ], *pArgs[10], *aPtr = NULL, *sPtr;
    int aCount;
    pid_t pid;

    while(1) {
        write(1, "\e[1;31mmyBash \e[1;32m# \e[0m", 27);
        read(0, bBuffer, BUFSIZ);

        sPtr = bBuffer;
        aCount = 0;

        do {
            aPtr = strsep(&sPtr, " ");
            pArgs[aCount++] = aPtr;
        } while(aPtr);

        pArgs[aCount-2][strlen(pArgs[aCount-2])-1] = '\0';

        // Debug code to output pArgs content
        write(1, "|>", 2);
        write(1, pArgs[0], strlen(pArgs[0]));
        write(1, "<|", 2);

        if(strlen(pArgs[0]) > 1) {
            pid = fork();

            if(pid == -1) {
                perror("fork");
                exit(1);
            }

            if(pid == 0) {
                execvp(pArgs[0], pArgs);
                exit(0);
            }
        }
    }

    return 0;
}
#包括
#包括
#包括
#包括
int main(int argc,字符**argv){
char bBuffer[BUFSIZ],*pArgs[10],*aPtr=NULL,*sPtr;
国际帐户;
pid_t pid;
而(1){
写(1,“\e[1;31mmyBash\e[1;32m\e[0m],27);
读取(0,bBuffer,BUFSIZ);
sPtr=bBuffer;
a账户=0;
做{
aPtr=STREP(&sPtr,“”);
pArgs[aCount++]=aPtr;
}while(aPtr);
pArgs[account-2][strlen(pArgs[account-2])-1]='\0';
//调试代码以输出pArgs内容
写(1,“;>”,2);
写(1,pArgs[0],strlen(pArgs[0]);
写(1),“
inti;
对于(i=0;i<10;i++)
pArgs[i]=NULL;

您的问题是在读取数据后没有添加空字符。因此,
strep
调用不知道在哪里停止。在C中,字符串必须以空字符结尾(称为终止空字符)

由于
execvp
将读取参数直到第一个空指针,因此我不知道现在应该清除哪个数组。但是
do
循环已经添加了该空指针,它是上次调用
strep
返回的空指针

当然,只需清除bBuffer(扫描第一个命令后,
*pArgs
指向的数据)也可以解决这个问题。请注意,在第一次扫描之前也必须这样做,因为不能假设
bBuffer
数组中的字符被初始化为任何合理的值

memset(bBuffer, 0, sizeof bBuffer);
将其放在
read
调用之前(但在任何情况下,最大限度地只读
BUFSIZE-1
,因为终止的空字符也必须有空格!)


但是正如我上面所示,您不需要这个memset调用。只需手动添加终止的空字符。

我用memset()回答,然后删除了我的答案,因为很难解释为什么sizeof(pArgs)在这种情况下是可以的,但在另一种情况下可能不可以(例如,pArgs的类型是char**).1到“for”循环,-1对于此上下文中的memset。您应该保留它。memset仍然是正确的,并且在速度是一个问题时是更好的方法。(请参阅:)一个好的编译器可能会优化这个for循环到一个memset,无论如何我同意,最好删除这个memset。它并不总是正确的。循环总是有效的。如果你知道空指针是由空字节组成的,你可以这样做,但决不会注意到shell中的速度差异!memset()不能保证将指针的表示形式设置为NULL。“ptr=NULL;”与“memset(&ptr,0,sizeof(ptr)”不同。我刚刚重读了C FAQ,Dingo似乎是正确的。尽管NULL必须等于((void*)0,“零指针”的位模式可能与“零整数”的位模式不同"。我将删除memset,因为它在某些体系结构上无效。我不明白为什么我的答案被否决。显然,他的问题不是因为没有清除指针数组而产生的,而是其他地方的问题。因此,简单地显示清除该数组的正确方法是好的,但当然,显示如何纠正错误至少是个问题逻辑上很重要!我认为他的“无限循环”是故意的,你误读了这个问题。但我对此投了赞成票,因为这是提交者应该注意的重要信息。当然,我并不打算打破无限循环。看看阅读,假设BUFSIZ是255。你输入“echo hello”。然后缓冲区包含[echo HelloBlashBlusomerandomData……]。strep应该如何正常运行?仅仅清除指针数组是不行的。他真正想要的是清除bBuffer数组。但是,正如我在回答中所说的那样,这不是必需的。然而,我的建议是,他可以去掉do while循环后的='\0';行,这当然是错误的。他这样做是为了去掉'\n''字符。恐怕我完全忽略了那一行的用途。如果我像你建议的那样做bBuffer[s-1]='\0'而不是bBuffer[s]='\0',我仍然可以去掉这一行来清除'\n'字符。而且既然我必须清除这一行,那么最好是做s-1,而不是用strlen()来清除那条大而混乱的行。'仅清除“\n”字符。:)
// don't forget to add error handling at some point (s == -1)
ssize_t s = read(0, bBuffer, BUFSIZ-1);
bBuffer[s] = '\0';
memset(bBuffer, 0, sizeof bBuffer);