malloc、sizeof 和 strlen 函数可能发生冲突?
malloc, sizeof and strlen functions possible conflict?
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef struct _person
{
char *fname;
char *lname;
bool isavailable;
}Person;
Person *getPersonInstance(void)
{
Person *newPerson = (Person*) malloc(sizeof(Person));
if(newPerson == NULL)
return NULL;
return newPerson;
}
void initializePerson(Person *person, char *fname, char *lname, bool isavailable)
{
person->fname = (char*) malloc(strlen(fname)+1);
/*problematic behaviour if i write: person->fname = (char*) malloc (sizeof(strlen(fname)+1)); */
person->lname = (char*) malloc(strlen(lname)+1);
/*problematic behaviour if i write: person->lname = (char*) malloc (sizeof(strlen(lname)+1)); */
strcpy(person->fname,fname);
strcpy(person->lname,lname);
person->isavailable = isavailable;
return;
}
// test code sample
int main(void)
{
Person *p1 =getPersonInstance();
if(p1 != NULL)
initializePerson(p1, "Bronze", "Medal", 1);
Person *p2 =getPersonInstance();
if(p2 != NULL)
initializePerson(p2, "Silver", "Medalion", 1);
Person *p3 =getPersonInstance();
if(p3 != NULL)
initializePerson(p3, "Golden", "Section", 1);
printf("item1=> %10s, %10s, %4u\n",p1->fname, p1->lname, p1->isavailable);
printf("item2=> %10s, %10s, %4u\n",p2->fname, p2->lname, p2->isavailable);
printf("item3=> %10s, %10s, %4u\n",p3->fname, p3->lname, p3->isavailable);
return 0;
}
在 initializePerson() 内部,如果我使用:
person->fname = (char*) malloc (sizeof(strlen(fname)+1));
person->lname = (char*) malloc (sizeof(strlen(lname)+1));
当启用这两个代码行而不是我在上面的源代码中使用的代码行时,当我使用 CodeBlocks IDE 测试代码时,我可能会遇到 运行 时间错误。控制台很可能会冻结并停止工作。如果我使用 ubuntu 终端测试代码,无论输入数据的大小如何,它每天都可以正常工作。
问题:(现在,假设我们正在使用上一段中的 2 段代码)我知道 sizeof 计算字节数,而 strlen 计算字符数直到它找到 null...但是 sizeof 和 strlen当在 malloc() 中一起使用时,它们会在后台引起冲突吗?似乎是什么问题?为什么代码有如此不稳定、不可靠的行为?为什么?
sizeof
计算其参数的存储大小(可能是类型的表达式,或者只是类型本身)。所以,仔细看看这里的论点是什么:
strlen(fname)+1
这是 size_t
类型的表达式。 sizeof
将为您提供存储 size_t
(可能是 4 或 8)所需的任何字节数。
您想要的 足以存储您的字符串,因此只有 strlen()
的版本是正确的。在另一种情况下,您只保留 4 或 8 个字节,然后写入您未分配的内存位置 -> 未定义的行为.
附带说明:在 C 中明确不需要转换 void *
并且许多(但不是所有)C 编码器认为这是不好的做法。参见 this classic quesion。
sizeof(strlen(fname)+1)
没有任何意义。它给出了strlen
的结果类型的大小,它是一个4字节的整数。所以你最终分配的内存太少了。
使用这个:
person->fname = malloc(strlen(fname)+1);
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef struct _person
{
char *fname;
char *lname;
bool isavailable;
}Person;
Person *getPersonInstance(void)
{
Person *newPerson = (Person*) malloc(sizeof(Person));
if(newPerson == NULL)
return NULL;
return newPerson;
}
void initializePerson(Person *person, char *fname, char *lname, bool isavailable)
{
person->fname = (char*) malloc(strlen(fname)+1);
/*problematic behaviour if i write: person->fname = (char*) malloc (sizeof(strlen(fname)+1)); */
person->lname = (char*) malloc(strlen(lname)+1);
/*problematic behaviour if i write: person->lname = (char*) malloc (sizeof(strlen(lname)+1)); */
strcpy(person->fname,fname);
strcpy(person->lname,lname);
person->isavailable = isavailable;
return;
}
// test code sample
int main(void)
{
Person *p1 =getPersonInstance();
if(p1 != NULL)
initializePerson(p1, "Bronze", "Medal", 1);
Person *p2 =getPersonInstance();
if(p2 != NULL)
initializePerson(p2, "Silver", "Medalion", 1);
Person *p3 =getPersonInstance();
if(p3 != NULL)
initializePerson(p3, "Golden", "Section", 1);
printf("item1=> %10s, %10s, %4u\n",p1->fname, p1->lname, p1->isavailable);
printf("item2=> %10s, %10s, %4u\n",p2->fname, p2->lname, p2->isavailable);
printf("item3=> %10s, %10s, %4u\n",p3->fname, p3->lname, p3->isavailable);
return 0;
}
在 initializePerson() 内部,如果我使用:
person->fname = (char*) malloc (sizeof(strlen(fname)+1));
person->lname = (char*) malloc (sizeof(strlen(lname)+1));
当启用这两个代码行而不是我在上面的源代码中使用的代码行时,当我使用 CodeBlocks IDE 测试代码时,我可能会遇到 运行 时间错误。控制台很可能会冻结并停止工作。如果我使用 ubuntu 终端测试代码,无论输入数据的大小如何,它每天都可以正常工作。
问题:(现在,假设我们正在使用上一段中的 2 段代码)我知道 sizeof 计算字节数,而 strlen 计算字符数直到它找到 null...但是 sizeof 和 strlen当在 malloc() 中一起使用时,它们会在后台引起冲突吗?似乎是什么问题?为什么代码有如此不稳定、不可靠的行为?为什么?
sizeof
计算其参数的存储大小(可能是类型的表达式,或者只是类型本身)。所以,仔细看看这里的论点是什么:
strlen(fname)+1
这是 size_t
类型的表达式。 sizeof
将为您提供存储 size_t
(可能是 4 或 8)所需的任何字节数。
您想要的 足以存储您的字符串,因此只有 strlen()
的版本是正确的。在另一种情况下,您只保留 4 或 8 个字节,然后写入您未分配的内存位置 -> 未定义的行为.
附带说明:在 C 中明确不需要转换 void *
并且许多(但不是所有)C 编码器认为这是不好的做法。参见 this classic quesion。
sizeof(strlen(fname)+1)
没有任何意义。它给出了strlen
的结果类型的大小,它是一个4字节的整数。所以你最终分配的内存太少了。
使用这个:
person->fname = malloc(strlen(fname)+1);