2015-09-20 116 views
0

我的代码,当你键入这些被称为“最近的”返回字符指针:问题与功能

char* runRecent() { 
    FILE *ffp; 
    ffp = fopen("bash.txt","r"); 
    char line[MAXLINE]; 
    int fileItCount = 0; 
    for (int i = 0 ; i < numLinesinFile ; i++) { 
     fgets(line, sizeof(line), ffp); 
     if (fileCounter - 2 < 0){ 
      printf("No recent commands exist.\n"); 
      exit(EXIT_FAILURE); 
     } 
     if (i == (numLinesinFile - 2) && i >= 0) { 
      printf("Previous command: %s\n",line); 
      char * lineRet = strdup(line); 
      printf("line ret: %s\n",lineRet); //output: correct, something along the lines of "ls" or "ls -a" 
      printf("line ret: %d\n",&lineRet); //output: 1528174960 
      return lineRet; 
     } 
    } 
} 

的lineRet随后被传递给函数:

start(runRecent()); 

凡函数声明看起来像:

void start(char inputBuf[]){ 
    printf("input is %s\n",inputBuf); //prints the command "recent" instead of the previous command that was executed 
} 

为什么这会返回当前命令而不是前一个?

+1

不要忘记'free'运行结果'runRecent'。 – emlai

+0

@zenith我在哪里可以免费得到runRecent的结果? – sc1892353

+0

某处您可以访问其返回值以及将其释放的位置。 – emlai

回答

1

您的代码有很多问题,

  1. 函数并不总是返回一个值,这可能会导致未定义行为的情况下,函数永远不会到达return声明。这很明显,为什么这可能是原因,所以我不会详细解释它。

    您可以在函数结尾处添加一个默认返回,如return NULL;,但在将结果传递给printf()之前,您必须先检查NULL

  2. 还援引这里未定义行为

    printf("line ret: %d\n", &lineRet); 
    

    您观察到的行为可能的解释之一是未定义行为,将指针的正确方法是

    printf("line ret: %p\n", (void *) &lineRet); 
    

    别的被标准认为是未定义的行为。

  3. 没有检查strdup()没有返回NULL poitner,如果没有可用的内存可能会发生这种情况。这是不太可能的问题,但是你必须检查你的程序是否可以在任何条件下工作。

  4. 不检查fopen()没有返回NULL,这可能是这种情况时,例如文件无法读取当前用户或者当它是不可能打开它,它不存在于所有的,在任何情况下。

  5. start(runRecent());自动导致内存泄漏,您不需要释放每一个malloc(),因为内存将在程序结束时自动释放。但是,像这样的一些错误,你会遇到严重的麻烦,特别是因为你不检查strdup()是否返回了非指针NULL

    事实证明,编写一个程序将不会吃掉所有系统可用的内存,一个微小的内存泄漏和几分钟的运行就足以使其发生。

注意:启用编译器警告,你会两者不会问这样的问题不断的和了解C语言只是通过简单的归纳。