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

我是C的新手,请原谅我,如果这太明显了,但我在查找代码中导致分段错误的错误时遇到了问题。 我相信问题可能在于malloc()的使用,但我并不积极。

这是代码:

#include  #include  #include  #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()吗?

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

 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; } 

以类似的方式定义其他function。

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

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

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

另外考虑一下,前3个函数做同样的事情,你应该考虑改为使用一个函数。

希望我帮忙

编写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的类型myFirstNamewchar *出于某种疯狂的原因,该调用仍将是好好工作。

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

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

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

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

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