缓冲区大小问题

时间:2015-01-26 15:36:32

标签: c

我写了一个调用Unix脚本的C程序。该脚本将输出写入通过POPEN命令读取的文件。

在读取20多个字符的输出(例如“452088000104023512234”)时,通过现有代码将其转换为一些垃圾字符。

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

#define  OUTPUT_FILE_PATH  "/td/mbb/Projects/MBNA/Work/java.txt"
#define  SCRIPT_FILE_PATH  "/td/mbb/Projects/MBNA/Work/R/TDEncryptDecrypt/TDEncryptDecrypt/src/java.sh"

void waitAndExecuteScript(char* input)
{
    char scriptCmd[256];
    sprintf(scriptCmd, "%s  %s", SCRIPT_FILE_PATH, input);   

    int i = system(scriptCmd);  //execute command string

    FILE* fp = fopen ( OUTPUT_FILE_PATH , "rb" );

    while (1)
    {
        if(fp == NULL)
        {
            usleep(1000);
            fp = fopen (OUTPUT_FILE_PATH , "rb" );
        }
        else
        {
            fclose(fp);
            break;
        }
    }
}

char * java (char* str1)
{
    int i,l;
    char * resultval;
    char * buffer = NULL;
    long lSize = 0;
    size_t result = 0;
    FILE* pFile = NULL;
    char  removeCmd[256];

    waitAndExecuteScript(str1);

    //******************************reading input data in a file ************************

    pFile = fopen (OUTPUT_FILE_PATH , "rb" );
    if (pFile==NULL)
    {
        fputs ("File error",stderr);
        exit (1);
    }

    // obtain file size:
    fseek (pFile , 0 , SEEK_END);
    lSize = ftell (pFile);
    rewind (pFile);

    // allocate memory to contain the whole file:
    buffer = (char*) malloc (sizeof(char)*lSize + 1);   // 1 extra byte need to allocate to accomodate null character
    if (buffer == NULL)
    {
        fputs ("Memory error",stderr);
        exit (2);
    }

    // copy the file into the buffer:
    result = fread (buffer,1,lSize,pFile);
    if (result != lSize)
    {
        fputs ("Reading error",stderr);
        exit (3);
    }

    /* the whole file is now loaded in the memory buffer. */

    buffer[lSize] = '\0';                //make string null terminated so that printf will print it properly
    printf("result from script %s", buffer);

    resultval = buffer;    
    // terminate
    fclose (pFile);
    if(buffer != NULL)
    {
        free (buffer);
    }

    //wait here for 1ms 
    usleep(1000);

    return resultval;  //Return the result value of the script
}

2 个答案:

答案 0 :(得分:3)

您的目的是:

  1. 运行一些外部命令以写入文件

  2. 轮询以查看您是否可以打开文件(位于waitAndExecuteScript

  3. 之后立即阅读文件(位于java)。

  4. 此策略不起作用。除非您知道外部命令以原子方式创建文件(例如,通过将其写入另一个文件然后重命名),该文件将在完全写入之前存在并变为可读。请考虑以下顺序:

    1. 外部进程打开文件进行写入,但尚未写入任何内容

    2. waitAndExecuteScript成功打开空文件

    3. java读取空文件

    4. 外部进程写入数据。

    5. 如您所见,数据可能已部分写入。

      您应该做的是检查正在完成写作的过程。或者,将其写入管道并使用阻塞读取。

答案 1 :(得分:1)

你的记忆管理也存在缺陷:

resultval = buffer;    
...
if(buffer != NULL)
{
    free (buffer);
}
...
return resultval;  //Return the result value of the script

resultval = buffer使指针变量resultval指向与buffer点相同的位置。但是你free() - 编写了位于那里的内存块。因此,当您从resultval函数返回时,java()指向无效的内存位置。

如果你的平台是Linux,我建议你安装并使用Valgrind内存调试器来轻松发现这样的bug。