【问题标题】:Why am I getting a seg fault while calling strtok_r?为什么在调用 strtok_r 时出现段错误?
【发布时间】:2021-01-01 14:08:09
【问题描述】:

所以,每当我尝试调用 strtok_r 时,我都会遇到段错误,但我不完全确定原因。我在这段代码中遇到了这个错误。

我知道我的错误来自这部分代码,因为如果我要取出这个 while 循环,并简单地替换为 printf(str);我没有收到任何错误,并且打印正确。

下面是我的包含 strtok_r 的方法:

void parseCommand(char *str)
{
  char *curr;
  char *temp = str;
  char **args=NULL;

  int i = 0;
  curr=strtok_r(temp, " ", &temp);
  while(curr!=NULL){
    args[i]=curr;
    curr=strtok_r(NULL," ",&temp);
    i++;
  }

  for(int j = 0;j<i-1;j++){
    printf("%s", args[j]);
  }
}

如果我对 seg 错误的理解是正确的,这是因为我试图访问该进程无权访问的某种内存,但我不确定为什么。有什么帮助!

编辑:我曾尝试对此进行一些试验,并假设我的字符串末尾没有空终止符,但是当我添加该行时

strncat(cur,"\0",50);

在我的 while 循环内部,就在我分配给 args[i] 之前,会产生相同的结果。

编辑:更新 strtok_r 用法

【问题讨论】:

  • char **args=NULL ... args[i]=curr;。您从未为 args 分配任何空间。
  • 如果我的输入可以是可变长度的,我怎么知道要分配多少空间?
  • 如果输入字符串的长度为N,则最多有N/2个token。
  • @backwardforward 任何你想要的方式。有很多选择。如果需要,您可以猜测并重新分配更多。您可以分配比您以后需要的更多和“合适的大小”。还有很多其他方法。
  • 另请注意,您错误地调用了strtok_r。只有第一个调用应该通过temp。以下所有调用均应通过NULL

标签: c pointers segmentation-fault token strtok


【解决方案1】:

我看到两个问题:

  1. 没有分配给args的内存

  2. strtok_r的错误使用

要解决第一个问题,您可以在找到新令牌时使用realloc

要解决第二个问题,您需要使用str 调用一次strtok_r,然后在其余时间调用NULL

类似:

void parseCommand(char *str)
{
  char *curr;
  char **args=NULL;
  char *saveptr;  

  int i = 0;

  // Look for first token, i.e. pass str
  curr = strtok_r(str, " ", &saveptr);
  
  while(curr != NULL){
    // Allocate memory for the pointer
    char **p = realloc(args, (i + 1) * sizeof *p);
    if (p == NULL) exit(1);
    args = p;

    // Save the pointer
    args[i]=curr;
    i++;

    // Look for next token, i.e. pass NULL
    curr = strtok_r(NULL, " ", &saveptr);
  }

  for(int j = 0; j < i; j++){
    printf("%s\n", args[j]);
  }
}

当你调用函数时:

char some_text[] = "Hello how are you";
parseCommand(some_text);

不要像这样称呼

parseCommand("Hello how are you");  // Illegal

strtok_r 将修改传递的字符串,因此您必须传递一个可以修改的字符串。

【讨论】:

    猜你喜欢
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 2020-06-17
    • 1970-01-01
    • 2015-01-27
    相关资源
    最近更新 更多