在 c 中正确使用 malloc() 和 free()
Proper usage of malloc() and free() in c
我是 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() 的方式是否正确?
我也是新手,不过我觉得你的问题出在这里:
char* firstName;
firstName = getFirstName(firstName);
char* myfirstName = (char*)malloc(strlen(firstName)+1);
您正在对未初始化的 char 指针实施 strlen。
您必须指定一个最大长度(#define MAX_SIZE 64)并使用它,因为您不知道名称的长度。
也考虑一下,前3个函数也是一样的,你应该考虑用一个函数代替。
希望我能帮到你
您编写的用于输入数据的函数没有使用它们的参数(或者它们使用不正确)。因此,像这样声明它们是没有意义的:
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
指向的已分配内存。而函数returns什么都没有。
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] = '[=15=]';
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;
}
以类似的方式定义其他函数。
您不应在 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 也是如此。
编写 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 *
出于某种疯狂的原因,调用仍将正常工作。
我是 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() 的方式是否正确?
我也是新手,不过我觉得你的问题出在这里:
char* firstName;
firstName = getFirstName(firstName);
char* myfirstName = (char*)malloc(strlen(firstName)+1);
您正在对未初始化的 char 指针实施 strlen。 您必须指定一个最大长度(#define MAX_SIZE 64)并使用它,因为您不知道名称的长度。
也考虑一下,前3个函数也是一样的,你应该考虑用一个函数代替。
希望我能帮到你
您编写的用于输入数据的函数没有使用它们的参数(或者它们使用不正确)。因此,像这样声明它们是没有意义的:
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
指向的已分配内存。而函数returns什么都没有。
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] = '[=15=]';
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;
}
以类似的方式定义其他函数。
您不应在 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 也是如此。
编写 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 *
出于某种疯狂的原因,调用仍将正常工作。