简体   繁体   English

C中的struct malloc问题

[英]Trouble with struct malloc in C

I'm currently getting started with C, and can't come up with a solution for this. 我目前正在使用C,但无法为此提供解决方案。

The code: 编码:

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

struct {
   char *name;
   int ID;
   [...]
} example;  

int currentID = 1;

int new_example(char *name){

   char *the_name = malloc(strlen(name) * sizeof(char));
   example *test = malloc(sizeof(example));

   test->name = name;
   test->ID = currentID;
   currentID++;

   [...]

   return test->ID;
}

Now I know that I have to use malloc (and free) for the "name" member of that struct, as well as for the struct itself. 现在,我知道我必须对该结构的“名称”成员以及该结构本身使用malloc(和free)。 What I'm doing right now is just allocating memory to the_name, but the test->name has no memory allocated for it. 我现在正在做的只是向the_name分配内存,但是test-> name却没有为其分配内存。 So I guess my question is, how do I write test->name into the previously malloc'd memory? 所以我想我的问题是,如何将test-> name写入以前分配的内存中? Sorry if my question isn't clear enough, I don't really know how to explain it better. 抱歉,如果我的问题不够清楚,我真的不知道该如何更好地解释它。

Thanks in advance 提前致谢

Why don't you do something like this: 你为什么不做这样的事情:

  example *test = malloc(sizeof(example));

  test->name = malloc((strlen(name) + 1) * sizeof(char)); // +1 for null terminator
  test->ID = currentID;

  strcpy(test->name, name);//copy name contents

Point the pointer to the new memory 将指针指向新内存

char *the_name = malloc((strlen(name)+1) * sizeof(char));
example *test = malloc(sizeof(example));

test->name = the_name ;

And copy the string to it 并将字符串复制到它

strcpy( test->name , name )  ;

Notice that you need to allocate one more character for the null terminator: 注意,您需要为空终止符再分配一个字符:

strlen(name)+1) * sizeof(char)

It should look something like the following: 它看起来应该如下所示:

int new_example(char *name){

   example *test = malloc( sizeof *test ); // or calloc( 1, sizeof *test )
   if ( test ) // you should always check the result of malloc or calloc
   {   
     test->name = calloc( strlen( name ) + 1,   // + 1 for 0 terminator
                          sizeof *test->name );  
     if ( test->name )
     {
       strcpy( test->name, name );
       test->ID = currentID;
       currentID++;

       [...]
       return test->ID;
     }
     else
       free( test );
   }
   return -1; // error indication
}

Some notes: 一些注意事项:

  • I prefer using sizeof *test over sizeof ( example ) ; 我更喜欢使用sizeof *test不是sizeof ( example ) if I ever change the type of test , I don't have to worry about changing the corresponding type in the malloc or calloc call. 如果我更改了test的类型,则不必担心在malloccalloc调用中更改相应的类型。 Same for sizeof *test->name . sizeof *test->name By definition, sizeof ( char ) == 1, so that calloc call can be written calloc( strlen( name ) + 1, 1 ) , but I still like the explicit sizeof expression in case you decide to use wchar for name (or some other wide character type). 根据定义, sizeof ( char ) == 1,因此可以将calloc调用写成calloc( strlen( name ) + 1, 1 ) ,但是我仍然喜欢显式的sizeof表达式,以防万一您决定使用wchar作为名称(或其他名称)其他宽字符类型)。

  • calloc zeros out the memory it allocates. calloc将其分配的内存清零。 For most types this doesn't matter, but I makes sense when allocating space for strings. 对于大多数类型而言,这并不重要,但是在为字符串分配空间时我很有意义。

  • You should always check the result of malloc and calloc calls. 您应该始终检查malloccalloc调用的结果。 If you can't allocate memory for test , then you shouldn't try to allocate memory for test->name . 如果您不能为test分配内存,则不应尝试为test->name分配内存。 Similarly, if you can't allocate memory for test->name , that's probably an indication of something bad, so you should back out what you've done so far. 同样,如果您不能为test->name分配内存,则可能表明情况不好,因此您应该退出到目前为止所做的事情。

  • I am assuming that you are storing test to some persistent structure in the [...] section; 我假设您正在将test存储在[...]部分中的某些持久性结构中。 if not, you have a memory leak, because you lose the test pointer when the function exits. 如果不是,则存在内存泄漏,因为函数退出时会丢失test指针。

When you free the object, you'll want to free the name member first, like the following: 释放对象时,首先要释放name成员,如下所示:

void delete_example( example *ex )
{
  free( ex->name );
  free( ex );
}

There's no need to allocate the memory as a separate step (but if you must, remember to add another byte for the terminating '\\0' ). 不需要将内存分配为一个单独的步骤(但是,如果必须这样做,请记住为终止符'\\0'添加另一个字节)。 Use strdup() to assign test->name directly, with its own new copy of name : 使用strdup()直接分配test->name及其新的name副本:

int new_example(char *name){
  example *test = malloc(sizeof(example));

  test->name = strdup(name);
  test->ID = currentID;
  currentID++;

  [...]

  return test->ID;
}

do

   test->name = strdup(name);

strdup will measure the string, malloc some memory, copy the string and return the malloced memory to you strdup将测量字符串,malloc一些内存,复制该字符串并将malloc的内存返回给您

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM