rfgamaral
rfgamaral

Reputation: 16842

How do I clear this array pointer in C?

I'm trying do to a basic bash with the use of system calls but I'm having some little problems with a pointer array.

To resume my code, I read commands from the stdin with read() to a buffer then I use strsep() to separate the command from the arguments and all the arguments into an array. Then I create a new process with fork() and execute that command with the associated arguments with execvp().

All this goes into a infinite loop until the user types "quit" (not coded yet). The problem is that after the first iteration, I need *pArgs to be empty, for the next command and arguments. And I don't know how to do it...

Here's my code:

#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;
}

P.S: Sorry but I can't provide an input and output test case at the moment. Hopefully, this is not that hard to understand and fix that you guys don't need it. I'll post it later if it's needed though...

Just to clear things up:
I know I asked how to clear the array and I got an answer for that. But it seems now obvious to me that my problem wasn't that, but the garbage that the buffer was collecting as pointed out by litb. It makes more sense to terminate the string with the null character than to clear the array. That's why I'm marking litb's answer as right one.

Upvotes: 3

Views: 12880

Answers (2)

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507005

Your problem is that you don't add a null character after the data read. So the strsep calls don't know where to stop. In C, strings must be terminated by a null character (that's called the terminating null character).

// don't forget to add error handling at some point (s == -1)
ssize_t s = read(0, bBuffer, BUFSIZ-1);
bBuffer[s] = '\0';

With that in place, i don't see what array should be cleared now, since execvp will read arguments until the first null pointer. The do loop, however, adds that null pointer already, which is the null pointer returned by the last invocation of strsep.

The problem would of course also be solved too by just clearing bBuffer (the data where *pArgs is pointing to after the first command was scanned). Note that you have to do that also before scanning the first time, since you can't assume the chars in bBuffer array are initialized to any sensible values.

memset(bBuffer, 0, sizeof bBuffer);

Place that just before the read invocation (but in any case, read only maximally BUFSIZE-1, because the terminating null character must have space too!).

But as I've shown above, you don't need this memset call. Just add the terminating null character manually.

Upvotes: 3

rpetrich
rpetrich

Reputation: 32326

int i;
for (i = 0; i < 10; i++)
   pArgs[i] = NULL;

Upvotes: 9

Related Questions