【问题标题】:Allocating memory for structures in c为c中的结构分配内存
【发布时间】:2017-05-31 06:16:40
【问题描述】:
struct data{
char *key;
char *fname;
char *lname;
char *grade;
struct data *next;
};


 newnode = (struct data*)malloc(sizeof(struct data));
 strcpy(newnode->lname,lname);
 strcpy(newnode->grade,grade);
 strcpy(newnode->key,key);
 strcpy(newnode->fname,fname);
 newnode->next=NULL;

所以我正在研究哈希表。上面的代码崩溃了

struct data *newnode;
newnode = (struct data*)malloc(sizeof(struct data));
newnode->lname=(char*)malloc(strlen(lname)+1);
newnode->fname=(char*)malloc(strlen(fname)+1);
newnode->grade=(char*)malloc(strlen(grade)+1);
newnode->key=(char*)malloc(strlen(key)+1);

strcpy(newnode->lname,lname);
strcpy(newnode->grade,grade);
strcpy(newnode->key,key);
strcpy(newnode->fname,fname);
newnode->next=NULL;

这段代码似乎可以运行。这是为什么?据我了解,我已经为堆中的结构分配了内存。为什么我必须专门为每个对象做这件事?我还缺少什么吗?因为我真的不明白为什么底部的例子会起作用。

【问题讨论】:

  • 我们需要更多细节。例如,它会在哪一行崩溃?
  • 顺便说一句:strdup() 是一种比 malloc()/strcpy() 组合更好的复制字符串的方法。
  • 你还会想看强制性的“malloc的返回没有必要”,没必要。请参阅:Do I cast the result of malloc?
  • C 标准中没有的东西并不意味着它没有用。
  • strdup 在 POSIX 中也可以在 Windows 中使用,因此对于桌面程序来说非常便携。当它在一些不起眼的平台上编译失败时,很容易提供一个仿真。

标签: c heap-memory


【解决方案1】:

使用newnode = (struct data*)malloc(sizeof(struct data)),您只为struct data(一组指针)分配内存,但您不会为这些指针所指向的位置以及将字符串复制到的位置分配任何内存。因此,您必须分别为每个字符串分配内存,或者使用问题第二部分中的malloc,或者使用strdup,在一个命令中使用mallocstrcpy

struct data{
char *key;
char *fname;
char *lname;
char *grade;
struct data *next;
};


 newnode = (struct data*)malloc(sizeof(struct data));
 newnode->lname = strdup(lname);
 newnode-> grade = strdup(grade);
 newnode-> key = strdup(key);
 newnode-> fname = strdup(fname);
 newnode->next=NULL;

值得注意的是,strdup 需要一个字符串作为输入,即不是NULL 并且指向以\0 结尾的字符序列的指针。

【讨论】:

  • 非常感谢您和@SomeProgrammerDude。这是有道理的
【解决方案2】:

当你这样做时

newnode = malloc(sizeof(struct data));

你只为实际的结构分配内存。但是由于结构包含指针,您需要使这些指针指向某个有效的地方。单个 malloc 调用不知道结构的内容,也不知道它应该为所有指针分配多少额外内存。

例如,如果您声明一个普通指针变量,您不会期望能够在不分配内存的情况下仅将其用作strcpy 调用的目标,对吗?

【讨论】:

    【解决方案3】:

    当你 malloc 一个内部带有 char * 的结构时,它不会指向任何地方(至少是 NULL)所以你必须将 malloc 它作为一个正常的字符序列,因为你 必须知道目标字符串的大小。您可以使用mallocstrcpy 或仅使用strdup 以您的方式进行操作。

    【讨论】:

    • strncpy() 对于大多数用途来说都很糟糕 - 您需要跳过障碍以确保正确终止目的地。
    • @MichaelBurr 如果源字符串被正确终止,并且您以正确的方式使用 strncpy,它将提高代码的安全性和稳健性,避免缓冲区溢出。
    • @BetaRunner,strncpy 有它的用途,但不是作为 strcpy 的“安全”版本。可悲的是,这是一个被误解的功能。 malloc 返回的缓冲区也可能包含垃圾,因此不能保证 stuct 中的指针为 NULL。很可能不是。
    • @BetaRunner: Microsoft disallows strncpy() in their own code(以及较新的 MSVC 编译器默认情况下会向所有人发出警告),因为记录在案的使用问题。这里是a quote from Linus Torvalds about strncpy():“strncpy() 在很多方面对于 '\0' 来说都是一场可怕的灾难。我们可能应该禁止使用 strncpy()
    • 你们是对的人,我现在读了很多关于它的内容,我同意你的看法。
    猜你喜欢
    • 2013-06-05
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    相关资源
    最近更新 更多