正确使用c中的malloc()和free()

时间:2015-05-23 06:05:57

标签: c malloc

我是C的新手,请原谅我,如果这太明显了,但我遇到了一个问题,即在我的代码中发现导致分段错误的错误。我认为问题可能在于malloc()的使用,但我不是肯定的。

以下是代码:

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

#define         MAX_STRING      20

char*   getFirstName    (char*  firstName
                        )
{
  char* myfirstName = (char*)malloc(strlen(firstName)+1);
  printf("Please enter your first name: ");
  fgets(firstName,MAX_STRING,stdin);
  return(myfirstName);
}


char*   getLastName     (char* lastName
                    )
{
  char* mylastName = (char*)malloc(strlen(lastName)+1);

  printf("Please enter your last name: ");
  fgets(lastName,MAX_STRING,stdin);
  return(mylastName);
}


char*   getNickName     (char*  nickName
                        )
{
  char* mynickName = (char*)malloc(strlen(nickName)+1);
  printf("Please enter your nick name: ");
  fgets(nickName,MAX_STRING,stdin);
  return(mynickName);
}


char*   getCompleteName (const char*    firstName,
                         const char*    lastName,
                         const char*    nickName,
                         char*          completeName
                        )
{
  snprintf(completeName,MAX_STRING,"%s \"%s\"    %s",firstName,nickName,lastName);
}


int     main    ()
{
  char*         firstName;
  char*         lastName;
  char*         nickName;
  char*         completeName;

  firstName     = getFirstName(firstName);
  lastName      = getLastName(lastName);
  nickName      = getNickName(nickName);

  completeName  = getCompleteName(firstName,lastName,nickName,completeName);
  printf("Hello %s.\n",completeName);
 free(firstName);
 free(lastName);
 free(nickName);
 return(EXIT_SUCCESS);
}

我是否以正确的方式使用malloc()?

5 个答案:

答案 0 :(得分:1)

我也是新人,但我认为你的问题在这里:

char*         firstName;

firstName     = getFirstName(firstName);

char* myfirstName = (char*)malloc(strlen(firstName)+1);

你正在uninitialize char指针上实现strlen。 您必须指定最大len(#define MAX_SIZE 64)并使用它,因为您不知道名称的长度。

另外考虑一下,前3个函数的作用是相同的,你应该考虑改为使用一个函数。

希望我帮助

答案 1 :(得分:1)

您为输入数据而编写的函数不使用它们的参数(或者它们使用不正确)。因此,将它们声明为:

是没有意义的
char*   getFirstName    (char*  firstName );

在函数内部,分配内存并返回指向内存的指针。

此外,这句话:

char* myfirstName = (char*)malloc(strlen(firstName)+1);

无效。参数firstName的参数未初始化,也未指向任何字符串。

或者您尝试分配内存并在变量myfirstName中保存相应的地址:

char* myfirstName = (char*)malloc(strlen(firstName)+1);

然后尝试使用指针firstName读取数据:

fgets(firstName,MAX_STRING,stdin);

函数getCompleteName也无效。同样,completeName中没有分配的内存,您尝试连接其他字符串。该函数不返回任何内容。

char*   getCompleteName (const char*    firstName,
                         const char*    lastName,
                         const char*    nickName,
                         char*          completeName
                        )
{
  snprintf(completeName,MAX_STRING,"%s \"%s\"    %s",firstName,nickName,lastName);
}

考虑到函数fgets还在目标数组中包含新行字符。

因此,正确的函数可能如下所示:

char*   getFirstName()
{
    char* myfirstName = ( char* )malloc( MAX_STRING );

    printf( "Please enter your first name: " );

    fgets( myfirstName, MAX_STRING, stdin );

    size_t n = strlen( myfirstName );

    if ( n != 0 && myfirstName[n-1] == '\n' ) myfirstName[n-1] = '\0';

    return myfirstName;
}

char*   getCompleteName (const char*    firstName,
                         const char*    lastName,
                         const char*    nickName,
                        )
{
    const char *format = "%s \"%s\"    %s";

    size_t n = strlen( firstName ) + strlen( lastName ) + 
               strlen( nickName ) + strlen( format );

    completeName = ( char * )malloc( n );

    snprintf( completeName, n, format, firstName,nickName,lastName);

    return completeName;
}

以类似方式定义其他功能。

答案 2 :(得分:1)

撰写malloc电话的首选方式是

T *p = malloc( N * sizeof *p );

calloc类似:

T *p = calloc( N, sizeof *p );

转换是不必要的,在C89编译器下可以掩盖错误。

此次通话的问题

  char* myfirstName = (char*)malloc(strlen(firstName)+1);

firstName参数尚未初始化;它没有指向一个字符串,因此调用它上面的strlen是未定义的。在这种情况下,您应该使用MAX_STRING常量:

char *myFirstName = malloc( (MAX_STRING + 1) * sizeof *myFirstName );

在这种情况下,sizeof *myFirstName是多余的(根据定义sizeof (char)为1),但它不会伤害任何内容,如果您决定更改myFirstName的类型由于一些疯狂的原因,wchar *呼叫仍然可以正常工作。

答案 3 :(得分:0)

您不应在strlen()中使用malloc()来确定要分配到内存中的字节数。因为,在strlen()中指定的字符指针变量是“firstName,nickName,lastName”,它们存储未知位置的地址,这会导致给定的错误。 因此,您应该指定要为不同的字符指针变量分配的字节数,如下所示:

char* mylastName = (char*)malloc(150);

这里,150个字节将被分配到内存中,引用将被设置为char* mylastname

答案 4 :(得分:0)

char* myfirstName = (char*)malloc(strlen(firstName)+1);

在上面一行中,您使用的是firstName未初始化。 Strlen(firstName)仅在firstName具有您传递给函数的某个长度时才起作用。 同样适用于lastName和nickName。