如何在C中操作来自外部函数的char指针的值?

时间:2016-09-18 07:01:53

标签: c arrays function pointers parameters

我打算创建一个与scanf类似的函数,但我不需要定义char数组的长度,只需定义指针(并使用malloc())。

此时,我想让这个头文件只需要包含并在需要时使用它。

这是我的外部函数,在string.variavel.h

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

void pegastr( char *str ){

    char x , *guardaStr ;
    unsigned int i , j ;

    str = malloc( 1 );
    str[0] = '\0';

    for( j = 0 ; x != '\n' ; ++j ){

        x = getc( stdin );
        fflush( stdin );

        guardaStr = malloc( j );

        for( i = 0 ; i < j ; ++i ){
            guardaStr[i] = str[i];
        }

        str = malloc( 1 + j );

        for ( i = 0 ; i < j + 1 ; ++i ){
            if( guardaStr[i] == '\0' ){
                str[i] = x ;
            }else{
                str[i] = guardaStr[i] ;
            }
        }
        str[i] = '\0';
    }
}

这是我的函数调用并包含外部:

# include "string.variavel.h"

int main(void){

    char *palavrao , *torrada;

    pegastr( palavrao );

    pegastr( torrada );

    printf( "%s\n%s" , palavrao , torrada );

    return 0;
}

所以,我的问题是,如果我将pegastr()的所有代码复制到main()内部,当我尝试输出它工作的字符串时,但是,如果我不这样做并让代码保持现状,当我尝试输出main()中字符串的值时,我只在每个printf()获得(null)。

我认为我的问题是我在函数pegastr()的参数中发送/接收的地址,但我看不到需要更改的内容。

感谢你的帮助!

2 个答案:

答案 0 :(得分:1)

您粘贴的代码在内存处理方面存在很多问题。你有内存泄漏,你在那里做的不是很清楚。

我将根据我在阅读您的问题后所理解的问题解决您遇到的主要问题。这通常是关于指针及其工作原理。

如果要在函数中分配指针并返回它,可以A)传递指针指针或B)返回指针。

A)

// call: myallocator(&element, size)
void myallocator(char **element, size_t size)
{
    *element = malloc(size);
    // ...
}

B)

// call: element = myallocator(size)
char* myallocator(size_t size)
{
    char *mem;

    mem = malloc(size);
    // ...

    return mem;
}

答案 1 :(得分:0)

如果我将所有代码复制到main,它仍会打印null。通常,您的程序具有未定义的行为,并且无法正常工作(无论您将代码放在何处)

您的第一个问题是功能不会更改palavraotorrada的值。该函数只是用指针的调用,无论你在函数内部改变多少值,外部的变量仍然具有相同的值。

相反,你可以这样做:

 void pegastr( char **str ){  // Note double pointer
      ....
      *str = malloc(....
 }

 // Called like
 pegastr( &palavrao );

或喜欢

char* pegastr(){  // Return the malloc'ed pointer
      char * tmp = malloc(....

      ....

      return tmp;
 }


 // Called like

 palavrao = pegastr();

除此之外,您的代码还需要解决许多问题:

    for( j = 0 ; x != '\n' ; ++j ){
                 ^
                 x is uninitialized when the loop starts

        guardaStr = malloc( j );
                            ^
                            Do you want this when j is 0 ?
                            Or do you really want j + 1 here ?

此外,当您运行此代码第2,第3 ......时间时,您会发生内存泄漏。在使用新指针覆盖旧指针之前,需要释放内存。

内存泄漏也适用于:

         str = malloc( 1 + j );

在这里:

        if( guardaStr[i] == '\0' ){
            ^^^^^^^^^^^^
            Access outside allocated memory (e.g. when j is 0)

我建议您阅读realloc - 这是您的代码的更好选择。

使用realloc代码可能类似于:

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

void pegastr( char **str ){

    char *tmp;
    char x;
    unsigned int j ;

    tmp = malloc( 1 );
    if (tmp == NULL)
    {
        // Out of memory
        exit(1);
    }
    str[0] = '\0';

   j = 1; // Notice: j starts from 1
    while(1){

        x = getc( stdin );
        if (x == '\n')
        {
            // Don't copy the \n - just break the loop
            break;
        }
        fflush( stdin );

        // Insert the new char and a termination
        tmp = realloc(tmp, j+1);
        if (tmp == NULL)
        {
            // Out of memory
            exit(1);
        }
        tmp[j-1] = x;
        tmp[j] = '\0';

        // Increment j
        ++j;
    }

    // Update the input pointers value
    *str = tmp;
}



int main(void){

    char *palavrao , *torrada;

    pegastr( &palavrao );

    pegastr( &torrada );

    printf( "%s\n%s\n" , palavrao , torrada );

    free(palavrao);
    free(torrada);

    return 0;
}