Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用malloc时出错_C_Malloc - Fatal编程技术网

使用malloc时出错

使用malloc时出错,c,malloc,C,Malloc,我将char**input从main()传递到processinne()函数,然后再次将它从processinne()函数传递到getInput()函数,以便在读取文件时动态分配它 选中时,内部getInput()函数input正确分配了内存,但在processInne()的中使用时遇到运行时错误。问题是什么 下面是我的代码: int getInput(char ** input, const char * fileName) { int numInput = 0; int i,

我将
char**input
main()
传递到
processinne()
函数,然后再次将它从
processinne()
函数传递到
getInput()
函数,以便在读取文件时动态分配它

选中时,内部
getInput()
函数
input
正确分配了内存,但在processInne()的
中使用时遇到运行时错误。问题是什么

下面是我的代码:

int getInput(char ** input, const char * fileName)
{
    int numInput = 0;
    int i, j;
    char c;
    char tempInput[100];
    FILE * pFile;
    if((pFile = fopen(fileName, "r")) == NULL)
    {
        printf("Cannot read file %s\n", fileName);
        system("PAUSE");
        exit(1);
    }
    while(!feof(pFile))
    {
        c = fgetc(pFile);
        if(c == '\n') ++numInput;

    }
    /* printf("%d\n", numInput); */
    input = (char**)malloc(numInput * sizeof(char*)); /* #2 MALLOC input */
    rewind(pFile);
    for(i = 0; !feof(pFile); ++i)
    {
        fscanf(pFile, "%[^\n]%*c", tempInput);
        /* printf("%s\n", tempInput); */
        input[i] = (char*)malloc((strlen(tempInput) + 1) * sizeof(char)); /* #3 MALLOC input[] */
        strcpy(input[i], tempInput);
        /* printf("%s\n", input[i]); */ /* #4 PRINT OUT PERFECTLY */
        memset(tempInput, 0, sizeof(tempInput));
    }
    fclose(pFile);
    return numInput;
}
void processInExp(char ** input, char ** output, const char * fileName)
{
    int numFormula;
    int i;

    numFormula = getInput(input, fileName); /* #1 PASSING input */
    /* printf("%s\n", input[0]); */ /* #5 RUNTIME ERROR */
    output = (char**)malloc(numFormula * sizeof(char*));
    system("PAUSE");

    for(i = 0; i < numFormula; ++i)
    {
        convertIntoPost(input[i], output[i]);
        printf("%d. %s -> %s", (i + 1), input[i], output[i]);
    }

}
intgetInput(字符**输入,常量字符*文件名)
{
int numInput=0;
int i,j;
字符c;
字符输入[100];
文件*pFile;
if((pFile=fopen(文件名,“r”))==NULL)
{
printf(“无法读取文件%s\n”,文件名);
系统(“暂停”);
出口(1);
}
而(!feof(pFile))
{
c=fgetc(pFile);
如果(c=='\n')++numInput;
}
/*printf(“%d\n”,numInput)*/
输入=(char**)malloc(numInput*sizeof(char*);/*#2 malloc输入*/
倒带(pFile);
对于(i=0;!feof(pFile);+i)
{
fscanf(pFile,“%[^\n]%*c”,tempInput);
/*printf(“%s\n”,tempInput)*/
输入[i]=(字符*)malloc((strlen(tempInput)+1)*sizeof(字符));/*#3 malloc输入[]*/
strcpy(输入[i],临时输入);
/*printf(“%s\n”,输入[i]);*/*#4打印输出*/
memset(tempInput,0,sizeof(tempInput));
}
fclose(pFile);
返回numInput;
}
void processinfe(字符**输入,字符**输出,常量字符*文件名)
{
整数公式;
int i;
numFormula=getInput(输入,文件名);/*#1传递输入*/
/*printf(“%s\n”,输入[0]);*/*#5运行时错误*/
输出=(字符**)malloc(numFormula*sizeof(字符*);
系统(“暂停”);
对于(i=0;i%s”,(i+1),输入[i],输出[i]);
}
}

C
使用传递值传递函数参数。因此,从函数
getInput()
内部,您不能更改变量
input
,并期望该更改反映回传递给函数的实际参数中。为此,您需要一个指向要传递的变量的指针,就像在本例中一样,您需要这样做

   int getInput(char *** input, const char * fileName) { //notice the extra *
需要像这样称呼它

   char ** inp = NULL;
   getInput(&inp, ..........);
然后,
getInput()
将能够为函数内部的
*输入分配内存,这将反映在
inp

否则,在从
getInput()
返回后,实际参数仍将未初始化,进一步使用该参数(在您的情况下,在
processinfer()
函数中的
for
循环中)将导致错误

也就是说,还有两件事需要注意

  • 请在
    C
    中输入
    malloc()
    和family的返回值
  • 检查
  • C语言毫无例外地是按值传递的


    函数无法更改实际参数的值。

    正如Sourav提到的,C使用传递值传递参数,因此
    ProcessInE
    范围内的输入变量具有先前在main中分配的内存地址的值

    这会导致打印
    输入[0]
    时出现分段错误。这是因为
    printf
    正试图打印位于相对于先前分配内存的地址处的字符串,而不是在
    getInput
    函数中分配给输入的内存,您将字符串复制到该函数中


    解决方案是将指针传递给输入,因此函数签名如下:
    intgetinput(char***input,constchar*fileName)
    。然后,您需要将对
    input
    的任何引用更改为
    *input
    ,以便取消对指针的引用,并将
    input
    的指针传递到
    getInput
    ,如下所示:
    getInput(&input,fileName)
    ,而其他人则指出了按值传递的问题,还有一个问题是学习可以发生。无需预先读取文件以确定字符数或行数,然后回放文件以读取每行

    查看
    getline
    ,它返回读取的字符数。您需要做的就是保留一个
    sum
    变量,在读取所有行之后,只需返回(或更新作为参数提供的指针)就可以了。当然,您也可以在阅读该行后通过调用
    strlen
    fscanf
    fgets
    执行相同的操作

    下面是一个简短的示例,它一次读取一个文本文件,同时确定字符数(不带
    换行符
    ),并将该信息返回给调用函数。正如您需要在
    getInput
    中传递指向指针数组的指针一样,我们将使用作为参数传递的指针将
    字符
    计数返回给调用函数。如果声明并调用函数读取文件,如下所示:

    size_t nline = 0;       /* placeholders to be filled by readtxtfile */
    size_t nchar = 0;       /* containing number of lines/chars in file */
    ...
    char **file = readtxtfile (fn, &nline, &nchar);
    
        while (fgets (tempInput, MAXL, pFile) != NULL) {
            nchr = strlen (tempInput);
            while (nchr && (tempInput[nchr-1] == '\n' || tempInput[nchr-1] == '\r'))
                tempInput[--nchr] = 0;     /* strip newlines & carriage returns */
            input[i++] = strdup (tempInput);    /* allocates & copies tempInput */
        }
        numInput = i;
    
    通过在调用函数中声明变量,然后将指向变量的指针作为参数传递(使用urnary
    &
    ),可以更新函数中的值,并使这些值可在
    main
    中使用(或调用
    readtxtfile
    的任何函数)

    举例说明这些要点可以是:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define NMAX 256
    
    char **readtxtfile (char *fn, size_t *idx, size_t *sum);
    void prn_chararray (char **ca);
    void free_chararray (char **ca);
    
    int main (int argc, char **argv) {
    
        size_t nline = 0;       /* placeholders to be filled by readtxtfile */
        size_t nchar = 0;       /* containing number of lines/chars in file */
        char *fn = argc > 1 ? argv[1] : NULL;/* if fn not given, read stdin */
    
        /* read each file into an array of strings,
         * number of lines/chars read updated in nline, nchar
         */
        char **file = readtxtfile (fn, &nline, &nchar);
    
        /* output number of lines read & chars read and from where  */
        printf ("\n read '%zu' lines & '%zu' chars from file: %s\n\n", 
                nline, nchar, fn ? fn : "stdin");
    
        /* simple print function to print all lines */
        if (file) prn_chararray (file);
    
        /* simple free memory function */
        if (file) free_chararray (file);
    
        return 0;
    }
    
    /* simple function using getline to read any text file and return
     * the lines read in an array of pointers. user is responsible for
     * freeing memory when no longer needed
     */
    char **readtxtfile (char *fn, size_t *idx, size_t *sum)
    {
        char *ln = NULL;                /* NULL forces getline to allocate  */
        size_t n = 0;                   /* line buf size (0 - use default)  */
        ssize_t nchr = 0;               /* number of chars actually read    */
        size_t nmax = NMAX;             /* check for reallocation           */
        char **array = NULL;            /* array to hold lines read         */
        FILE *fp = NULL;                /* file pointer to open file fn     */
    
        /* open / validate file or read stdin */
        fp = fn ? fopen (fn, "r") : stdin;
        if (!fp) {
            fprintf (stderr, "%s() error: file open failed '%s'.", __func__, fn);
            return NULL;
        }
    
        /* allocate NMAX pointers to char* */
        if (!(array = calloc (NMAX, sizeof *array))) {
            fprintf (stderr, "%s() error: memory allocation failed.", __func__);
            return NULL;
        }
    
        /* read each line from stdin - dynamicallly allocated   */
        while ((nchr = getline (&ln, &n, fp)) != -1)
        {
            /* strip newline or carriage rtn    */
            while (nchr > 0 && (ln[nchr-1] == '\n' || ln[nchr-1] == '\r'))
                ln[--nchr] = 0;
    
            *sum += nchr;               /* add chars in line to sum         */
    
            array[*idx] = strdup (ln);  /* allocate/copy ln to array        */
    
            (*idx)++;                   /* increment value at index         */
    
            if (*idx == nmax) {         /* if lines exceed nmax, reallocate */
                char **tmp = realloc (array, nmax * 2);
                if (!tmp) {
                    fprintf (stderr, "%s() error: reallocation failed.\n", __func__);
                    exit (EXIT_FAILURE); /* or return NULL; */
                }
                array = tmp;
                nmax *= 2;
            }
        }
    
        if (ln) free (ln);              /* free memory allocated by getline */
        if (fp != stdin) fclose (fp);   /* close open file descriptor       */
    
        return array;
    }
    
    /* print an array of character pointers. */
    void prn_chararray (char **ca)
    {
        register size_t n = 0;
        while (ca[n])
        {
            printf (" arr[%3zu]  %s\n", n, ca[n]);
            n++;
        }
    }
    
    /* free array of char* */
    void free_chararray (char **ca)
    {
        if (!ca) return;
        register size_t n = 0;
        while (ca[n])
            free (ca[n++]);
        free (ca);
    }
    
    接下来,您的分配不需要强制转换为
    (char*)
    malloc
    calloc
    的返回仅仅是分配的内存块的指针(即地址)。(无论为什么分配内存都是一样的)不需要
    sizeof(char)
    。它总是
    1
    。所以只要写下:

    input[i] = malloc (strlen(tempInput) + 1); 
    strcpy (input[i], tempInput);
    
    分配
    复制
    更方便的方法是使用
    s
    
    for(i = 0; !feof(pFile); ++i) {
        fscanf(pFile, "%[^\n]%*c", tempInput); 
        /* printf("%s\n", tempInput); */ 
        input[i] = (char*)malloc((strlen(tempInput) + 1) * sizeof(char)); 
        strcpy(input[i], tempInput); 
        printf("%s\n", input[i]); 
        memset(tempInput, 0, sizeof(tempInput)); 
    } 
        for(i = 0; i < numInput; ++i) {
        convertIntoPost(input[i], output[i]);
    }
    
        while (fgets (tempInput, MAXL, pFile) != NULL) {
            nchr = strlen (tempInput);
            while (nchr && (tempInput[nchr-1] == '\n' || tempInput[nchr-1] == '\r'))
                tempInput[--nchr] = 0;     /* strip newlines & carriage returns */
            input[i++] = strdup (tempInput);    /* allocates & copies tempInput */
        }
        numInput = i;
    
    input[i] = malloc (strlen(tempInput) + 1); 
    strcpy (input[i], tempInput);
    
    input[i++] = strdup (tempInput);    /* allocates & copies */
    
    memset(tempInput, 0, sizeof(tempInput));
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAXL 256
    
    /* dummy function */
    void convertIntoPost (char *in, char **out)
    {
        size_t i = 0, len = strlen (in);
        *out = calloc (1, len + 1);
    
        for (i = 0; i < len; i++) {
            (*out)[len-i-1] = in[i];
        }
    }
    
    int main (int argc, char **argv) {
    
        char tempInput[MAXL] = {0};
        char **input = NULL, **output = NULL;
        size_t i = 0, numInput = 0;
        size_t nchr = 0;
        FILE *pFile = NULL;
    
        pFile = argc > 1 ? fopen (argv[1], "r") : stdin;
    
        if (!pFile) {
            fprintf (stderr, "error: file open failed '%s'.\n", 
                    argv[1] ? argv[1] : "stdin");
            return 1;
        }
    
        input  = calloc (1, MAXL);  /* allocate MAXL pointer for input & output   */
        output = calloc (1, MAXL);  /* calloc allocates and sets memory to 0-NULL */
    
        if (!input || !output) {    /* validate allocation */
            fprintf (stderr, "error: memory allocation failed.\n");
            return 1;
        }
    
        while (fgets (tempInput, MAXL, pFile) != NULL) {
            nchr = strlen (tempInput);
            while (nchr && (tempInput[nchr-1] == '\n' || tempInput[nchr-1] == '\r'))
                tempInput[--nchr] = 0;
            input[i++] = strdup (tempInput);    /* allocates & copies */
        }
        numInput = i;
    
        fclose (pFile);
    
        /* call convertIntoPost with input[i] and &output[i] */
        for (i = 0; i < numInput; ++i) {
            convertIntoPost (input[i], &output[i]);
            printf (" input[%2zu]: %-25s  output[%2zu]: %s\n",
                    i, input[i], i, output[i]);
        }
    
        /* free all memory */
        for (i = 0; i < numInput; ++i) {
            free (input[i]), free (output[i]);
        }
        free (input), free (output);
    
        return 0;
    }
    
    $ ./bin/feoffix ../dat/captnjack.txt
     input[ 0]: This is a tale             output[ 0]: elat a si sihT
     input[ 1]: Of Captain Jack Sparrow    output[ 1]: worrapS kcaJ niatpaC fO
     input[ 2]: A Pirate So Brave          output[ 2]: evarB oS etariP A
     input[ 3]: On the Seven Seas.         output[ 3]: .saeS neveS eht nO
    
    gcc -Wall -Wextra -o progname progname.c -g
    
    gcc -Wall -Wextra -finline-functions -Ofast -o progname progname.c