我写了以下代码:
char arrA[] = "something.";
char arrB[ strlen(arrA) + 5];
我的代码模糊不清。我收到了错误的输出。首先,根据我的问题,问题是在数组声明中使用strlen
。在编译时分配内存,并在运行时执行函数。但我没有在运行时收到错误。我的代码编译正确,但它没有像我想象的那样工作。最好的部分是我在代码中的任何地方都没有使用这些数组。我只是在宣布他们
为什么我在编译时没有错误?
为什么我的代码输出是意外的?
当我评论第二个声明时,我得到了正确的输出
我还尝试打印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(®ex, "^ *([1-9]+) ?");
executeRegex(®ex, 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(®ex, "[1-9]+/");
executeRegex(®ex, 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;
}
答案 0 :(得分: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
将被终止。如果id_proc
未终止并传递给printf("%s")
垃圾,很可能会出现在id_proc
的内容之后。