简体   繁体   English

如果注释了其他方法中的printf,则不显示返回值

[英]return value is not displayed if printf in the other method is commented

It seems that something weird is happening in my code below. 在下面的代码中似乎发生了一些奇怪的事情。 When any of the printf in the nthtoken() is commented, no token is displayed in main(), but when any of the nthtoken()'s printf is uncommented, token is displayed in main. 当对nthtoken()中的任何printf进行注释时,在main()中不显示任何令牌,但是当对nthtoken()的任何printf进行注释时,则在main中显示令牌。

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

 char *nthtoken (char *origStr, char *delimiters, int nth);

 int main (void) {

      char *str = "in principio creavit deus caelum et terram";
      char *delims = " ";

      char *tok = nthtoken (str, delims, 3);
      printf ("token: %s\n", tok);

      return (EXIT_SUCCESS);
 }

 char *nthtoken (char *origStr, char *delimiters, int nth) {

      char str[strlen (origStr)];
      strncpy (str, origStr, strlen (origStr) + 1);

      char *token = NULL;
      token = strtok (str, delimiters);
      // printf ("first token: %s\n", token);

      int i = 0;
      for (i = 0; i < nth; i++) {
           token = strtok (NULL, delimiters);
           //printf ("token inside the loop: %s\n", token); 
      }
      // printf ("token before returning to main(): %s\n", token);
      return token;
 }

This is a classic mistake. 这是一个经典的错误。 token is local. 令牌是本地的。 Returning it would produce unpredictable result. 返回它会产生不可预测的结果。 You might get it in printf, if it hasn't been over written, but it is not guaranteed and you should not do it. 如果尚未覆盖它,可以在printf中得到它,但是不能保证它也不要这样做。 Bottom line is that upon function termination local variables are out of scope and technically no longer exist to compiler or run time. 最重要的是,函数终止时,局部变量超出范围,从技术上讲,它们不再存在于编译器或运行时。

Either malloc and copy the token to it (and free it in main) or pass it to the function as an out parameter, for instance 例如,要么malloc并将令牌复制到它(并在main中释放它),要么将其作为out参数传递给函数。

char * ret_string = malloc(MAX_SIZE); // ensure this is always sufficiently large
strcpy(ret_string, token);
return ret_string;

Don'f forget to free the malloc memory in main. 不要忘记释放main中的malloc内存。

Edit: Thread safety note - As @grhegde suggested, Just for the record, strtok is not thread safe.If you are in a multithreaded environment, then you better find an alternative. 编辑: 线程安全说明 -如@grhegde所建议,仅作记录,strtok并不是线程安全的。如果您在多线程环境中,则最好找到替代方法。

To further explain this, strtok uses a global buffer to keep track of tokens, this means that it cannot be called for tokenizing another string while one string is being tokenized A standard solution to do this is often given with a function called strtok_r (r for re-entrant) where the implementation uses a local buffer for each call and hence can be called easily from multiple threads. 为了进一步说明这一点,strtok使用全局缓冲区来跟踪令牌,这意味着在对一个字符串进行令牌化时无法调用它来对另一个字符串进行令牌化 。为此的标准解决方案通常是使用称为strtok_r(r的函数可重入),其中实现为每个调用使用本地缓冲区,因此可以从多个线程轻松地调用。

Instead of using malloc and taking overhead of free you can work this way also... 不用使用malloc并节省大量开销,您还可以通过这种方式工作...

#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

 char *nthtoken (char *str, char *delimiters, int nth);

 int main (void) {

      char str[] = "in principio creavit deus caelum et terram";
      char *delims = " ";

      char *tok = nthtoken (str, delims, 3);
      printf ("token: %s\n", tok);

      return (EXIT_SUCCESS);
 }

 char *nthtoken (char *str, char *delimiters, int nth) {

      char *token = NULL;
      token = strtok (str, delimiters);
      // printf ("first token: %s\n", token);

      int i = 0;
      for (i = 0; i < nth; i++) {
                token = strtok (NULL, delimiters);
               //printf ("token inside the loop: %s\n", token); 
      }
      // printf ("token before returning to main(): %s\n", token);
       return token;
}

This is called dangling pointer issue. 这称为悬空指针问题。

{
  char *token = NULL;
  ....

  return token;
} 

http://en.wikipedia.org/wiki/Dangling_pointer http://en.wikipedia.org/wiki/Dangling_pointer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM