0

我有这个程序可以读取一个字符串并将其分成三个部分。第一部分是操作码,第二部分是数据,第三部分是密钥。

使用示例:

put this is stackoverflow

opcode: put 
data: this is
key: stackoverflow

代码主要:

 int main(int argc, char **argv){
          char command[MAX_MSG];
          fgets(command, sizeof(command), stdin);
          char *data;char *key;
          command[strcspn (command, "\n")] = '\0';
          char *aux_command_key = strdup(command);
          char *aux_command_data = strdup(aux_command_key);
          char *opcode = strtok(command, " ");          
          int success = 0;

          if(strcmp(opcode, "put") == 0){
                key = strdup(getKey(aux_command_key, opcode));
                if(key == NULL){
                       printf("Invalid number of arguments.\n");
                       return -1;
                 }

                 else
                       data = getData(aux_command_data, opcode, key);
          }
          printf("opcode: %s\n",opcode);
          printf("data: %s\n",data);
          printf("key: %s\n",key);               
          free(aux_command_key);
          free(aux_command_data);
}

我的问题是,当我在没有密钥的情况下运行程序时,它给我的结果是分段错误,而不是:“无效的参数数量”。我不知道为什么会这样。谢谢。

4

2 回答 2

0

好吧,如果您在不提供密钥的情况下运行程序,大概getKey(aux_command_key, opcode)会返回NULL

strdup()如果参数不是有效的字符串指针,则具有未定义的行为。(换句话说,不要将空指针传递给strdup())。

POSIX 标准对库函数的一般描述如下(C 标准有类似的语言,但strdup()它是 POSIX 的一部分,而不是 C 标准):

2.1.1 功能的使用和实现

除非在随后的详细描述中另有明确说明,否则以下每个陈述均适用于所有功能:

  1. 如果函数的参数具有无效值(例如函数域之外的值,或程序地址空间之外的指针,或空指针),则行为未定义。

...

假设参数必须是有效的,除非文档明确声明处理某些无效值是几乎任何 API 都遵循的一个很好的经验法则。请参阅:“编程的基本规则 - 函数参数及其使用方式”

于 2013-10-31T21:38:18.657 回答
0

您正在getKey使用指令进行调用put,并且您说您没有在输入中提供足够数量的参数。因此,在我看来,getKey它将返回NULL。你不能strdup用打电话NULL

我的建议:首先,调用getKey,然后,如果它没有返回NULL,你可以复制它:

  if(strcmp(opcode, "put") == 0){
        key = getKey(aux_command_key, opcode);
        if(key == NULL){
               printf("Invalid number of arguments.\n");
               return -1;
         }
        else {
               key = strdup(key);
               data = getData(aux_command_data, opcode, key);
         }
  }
于 2013-10-31T21:40:05.723 回答