0

私は次のコードを書きました:

char arrA[] = "something.";
char arrB[ strlen(arrA) + 5];

そして、私のコードは漠然と動作します。間違った出力が表示されます。まず、私によれば、問題はstrlen配列宣言での使用です。コンパイル時にメモリが割り当てられ、実行時に関数が実行されるため。しかし、実行時にエラーは発生しませんでした。コードは正しくコンパイルされましたが、思ったとおりに機能していません。最良の部分は、コードのどこにもこれらの配列を使用していないことです。私はそれらを宣言しているだけです。
コンパイル時にエラーが発生しなかったのはなぜですか?
コード出力が予期しないのはなぜですか?

この2番目の宣言にコメントすると、正しい出力が得られます。
また、を印刷してみましたsizeof arrB私が15を得たものを推測します。
これは、正しく機能していることを意味します。しかし、出力は混乱していて、正しく機能していないはずです。
ここで何が起きてるの。宣言しているだけで、どこにも使用していないことがコードに悪影響を与えるのはなぜですか?

私の実際のコードは大きすぎて異なります。そのコードを使用してこのエラーを説明することは不可能です。しかし、私はそのコードも共有しています。私のコードのこの問題は、関数portClearerと配列にありcompleteCommandます。

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

int strintToInt(char *str, int len);
void read_command_output(char*, char*, int);
void processIdFinder(char*);
void portClearer(char*);
void compileRegex(regex_t*, char*);
void executeRegex(regex_t*, char*, size_t, regmatch_t*, int);

int main()
{   
    processIdFinder("dispatcher");
    portClearer("4444");
    return 0;
}

void read_command_output(char* command, char* buf, int buf_len){

    FILE *ps_output_file;
    if ((ps_output_file = popen(command,"r"))== NULL){
        printf("error\n");
        exit(1);
    }

    if(fgets(buf, buf_len, ps_output_file)==NULL)
        printf("%s\n",buf);

    fclose(ps_output_file);

    return;
}

void compileRegex(regex_t* regexPtr, char* pattern){

    if( regcomp(regexPtr, pattern, REG_EXTENDED) ){ 
        fprintf(stderr, "Could not compile regex\n");
        exit(1); 
    }
}

void executeRegex(regex_t* regex, char* buf, size_t nmatch, regmatch_t* reg_matches, int flags){

    char errmsgbuf[100];
    int err_ret;
    err_ret = regexec(regex, buf, nmatch, reg_matches, flags);
    if( !err_ret ){
        //puts("Match");
        return;    
    }
    else if( err_ret == REG_NOMATCH ){
            puts("No match");
            exit(1);
    }
    else{
            regerror(err_ret, regex, errmsgbuf, sizeof(errmsgbuf));
            fprintf(stderr, "Regex match failed: %s\n", errmsgbuf);
            exit(1);
    }
}

int strintToInt(char *str, int len)
{
    int iter, pow_iter, num=0;
    for(iter = 0, pow_iter = len-1; iter < len; iter++, pow_iter--)
    {
        num += (str[iter]-48)* ((int) pow(10,pow_iter));
    }
    return num;

}

void processIdFinder(char* commandName){

    char buf[100], id_proc[10];
    regex_t regex;
    regmatch_t reg_matches[2];

    char command[] = "/bin/ps -C ", commandGrep[] = " | grep ";
    char completeCommand[ strlen(command) + strlen(commandGrep) + 2 * 12];
    //"/bin/ps -C supervisor | grep supervisor"

    strcpy(completeCommand, command);
    strcat(completeCommand, commandName);
    strcat(completeCommand, commandGrep);
    strcat(completeCommand, commandName);

    read_command_output(completeCommand, buf, 100);

    compileRegex(&regex, "^ *([1-9]+) ?");

    executeRegex(&regex, buf, (size_t) 2, reg_matches, 0);

    //fetching result
    //printf("%d and %d  ----- %c and %c\n",reg_matches[1].rm_so,reg_matches[1].rm_eo,buf[reg_matches[1].rm_so],buf[reg_matches[1].rm_eo - 1]);
    strncpy(id_proc,buf+reg_matches[1].rm_so, reg_matches[1].rm_eo - reg_matches[1].rm_so);
    printf("(%s)\n",id_proc);
    printf("%d\n",strintToInt(id_proc,strlen(id_proc))); //its important to write strlen here not 10

    return;
}

void portClearer( char* portNo){

    char buf[100], id_proc[10];
    regex_t regex;
    regmatch_t reg_matches[2];

    char command[] = "/bin/netstat -nlp | grep ";
    char completeCommand[ strlen(command) + 5 ]; 
    //char completeCommand[ 25 + 5 ]; 
    printf("%d\n", sizeof(completeCommand));

    //strcpy(completeCommand, command);
    //strcat(completeCommand, portNo);

    read_command_output("/bin/netstat -nlp | grep 4444", buf, 100);

    compileRegex(&regex, "[1-9]+/");

    executeRegex(&regex, buf, (size_t) 1, reg_matches, 0);

    //fetching result
    //printf("%d and %d  ----- %c and %c\n",matches[0].rm_so,matches[0].rm_eo,buf[matches[0].rm_so],buf[matches[0].rm_eo - 1]);
    strncpy(id_proc,buf+reg_matches[0].rm_so, reg_matches[0].rm_eo - reg_matches[0].rm_so-1);
    printf("(%s)\n",id_proc);
    printf("%d\n",strintToInt(id_proc,strlen(id_proc))); //its important to write strlen here not 10

    return;
}
4

1 に答える 1

4

これは可変長配列です(C99で導入されました):

char completeCommand[ strlen(command) + 5 ];

これは、コンパイラでC99サポートが有効になっている場合にコンパイルされる理由を説明しています。

これは正しくありません:

if(fgets(buf, buf_len, ps_output_file)==NULL)
    printf("%s\n",buf);

失敗した場合に使用bufしているためfgets()(出力が混乱している可能性があります)。そのはず:

if(fgets(buf, buf_len, ps_output_file)!=NULL)
    printf("%s\n",buf);

strncpy()ヌルターミネータは追加されませんが、ソースバッファからデスティネーションバッファにコピーされる可能性があることに注意してください。id_procこれは、 nullで終了することが保証されていないことを意味します。がnullで終了していない場合、ガベージにid_proc渡されます。ほとんどの場合、の内容の後に表示されます。printf("%s")id_proc

于 2012-10-30T14:44:40.190 に答える