Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在c中使用malloc typedef结构?_C_Struct_Malloc_Typedef - Fatal编程技术网

如何在c中使用malloc typedef结构?

如何在c中使用malloc typedef结构?,c,struct,malloc,typedef,C,Struct,Malloc,Typedef,我们的老师让我们制作一个视频俱乐部菜单,他给了我们一些结构: typedef struct date { int day, month, year; }date; typedef struct directorInfo { const char* directorSurname; const char* directorName; }directorInfo; typedef struct movie { int id; const char* t

我们的老师让我们制作一个视频俱乐部菜单,他给了我们一些结构:

typedef struct date
{
    int day, month, year;
}date;


typedef struct directorInfo
{
    const char* directorSurname;
    const char* directorName;
}directorInfo;


typedef struct movie
{
    int id;
    const char* title;
    directorInfo* director;
    date* releaseDate;
}movie;
我很困惑,我不知道如何处理每一个问题。 这就是我所做的:

int main() 
{
    
    int totalMovies = 50;
    
    movie *movie_ptr = (movie*)malloc( totalMovies * sizeof(movie) );                               
    date *date_ptr = (date*)malloc( totalMovies * sizeof(date) );                                   
    directorInfo *directorInfo_ptr = (directorInfo*)malloc( totalMovies * sizeof(directorInfo) );   
    
    
    
    movie_ptr->title = (char*)malloc( 200 * sizeof(char) );                                                     
    directorInfo_ptr->directorName = (char*)malloc( 200 * sizeof(char) );
    
    movie_ptr[0].director->directorName = "John";

    printf("%s", movie_ptr[0].director->directorName);
有没有更快更专业的方法?我觉得这一切都错了,而且当我试图打印directorName时,它不会打印任何内容。
(我很抱歉这里的任何高级程序员看到这段代码,都会瞪大眼睛)

结构、嵌套结构的内存分配,需要遵循最顶层结构的分配,并深入到嵌套结构(如果它们是指针),内存没有分配,在这种情况下,每个结构指针都需要显式分配内存,例如在您的情况下

以下代码将分配
类型的
电影的
结构的
未初始化数组

// this created/allocates an array of 50 movies
movie *m = malloc( sizeof(movie) * 50);

// for each movie m[i]
for (int i = 0; i < 50; ++i)
{
    m[i].title = malloc( sizeof(char) * 128 ); // say title size is 128 characters;
    m[i].director = malloc( sizeof(director));
    m[i].director->directorName = malloc( sizeof(char) * 128 );
    m[i].director->directorSurname = malloc( sizeof(char) * 128 );
    m[i].releaseDate = malloc( sizeof(date));
} // repeat for others
//这创建/分配了一个包含50部电影的数组
movie*m=malloc(sizeof(movie)*50);
//每部电影m[i]
对于(int i=0;i<50;++i)
{
m[i].title=malloc(sizeof(char)*128);//假设标题大小为128个字符;
m[i].director=malloc(sizeof(director));
m[i].director->directorName=malloc(sizeof(char)*128);
m[i].director->directorSurname=malloc(sizeof(char)*128);
m[i].releaseDate=malloc(sizeof(date));
}//为其他人重复
同样,释放遵循反向路径,首先释放所有结构元素,然后释放实际结构

// Free loop

for (int i = 0; i < 50; ++i)
{
    free(m[i].releaseDate);
    free(m[i].directorName->directorName);
    free(m[i].directorName->directorSurname);
    free(m[i],director);
    free(m[i]);
} // repeat for others

free(m);
//自由循环
对于(int i=0;i<50;++i)
{
免费(m[i]。发布日期);
免费(m[i].directorName->directorName);
免费(m[i].directorName->directorSurname);
自由(m[i],董事);
自由(m[i]);
}//为其他人重复
自由(m);

< P>除非你将此代码编译为C++或使用一个古老的K&R C实现,否则你可以将“脱离代码”> MalOC/ >调用——这会节省一些混乱和维护的头痛。此外,您还可以将目标用作
sizeof
操作数:

movie *movie_ptr = malloc( totalMovies * sizeof *movie_ptr );      
由于表达式
*movie\u ptr
的类型是
movie
sizeof*movie\u ptr==sizeof(movie)
1。当
movie_ptr
的声明与实际的
malloc
调用分开时,这尤其有用:

movie *movie_ptr;

// a bunch of code here

movie_ptr = malloc( totalMovies * sizeof *movie_ptr );
这样,您就不必不断重复类型名,从而使维护变得更容易

现在,关于更大的问题——如何更好地组织针对此类问题的代码——这里有一些建议:

首先,我将抽象出读取、分配数据的逻辑,并将数据分配给不同类型的函数

例如,有一个函数专门用于从标准输入流读取日期:

int getDate( int *day, int *month, int *year )
{
  int success = 1;

  printf( "Release year: " );  
  if ( scanf( "%d", year ) != 1 )  // this is the barest minimum level
    success = 0;                   // of error handling, but it's better than nothing
  ...
  return success;
}
然后使用另一个函数获取该数据并分配一个
date
对象:

date *createDate( int day, int month, int year )
{
  date *d = malloc( sizeof *d );
  /**
   * ALWAYS check the result of malloc, calloc, or realloc before attempting
   * to use the pointer, since they will return NULL if they cannot 
   * satisfy the request.
   */
  if ( d ) // or if ( d != NULL )
  {
    d->day = day;
    d->month = month;
    d->year = year;
  }
  return d;
}
然后在主代码中,您可以这样调用它们:

int day, month, year;
date *d = NULL;

if ( getDate( &day, &month, &year ) )
  d = createDate( day, month, year );
或者,可以将这些操作组合到第三个功能中:

date *dateFromStdInput( void )
{
  int day, month, year;
  date *d = NULL;

  if ( getDate( &day, &month, &year ) )
    d = createDate( day, month, year );

  return d;
}
然后在主代码中调用:

date *d = dateFromStdInput();
I/O和内存分配是完全独立的操作,因此通常您希望编写单独的函数来处理每一个操作,以便在不影响另一个操作的情况下更改其中一个操作。这需要一些预先考虑,但最终它使代码更易于维护和更新

对导演信息执行类似操作,然后您可以创建一个新的
电影
对象,如下所示:

date *d = dateFromStdInput();
directorInfo *dir = dirFromStdInput();

char title[MAX_TITLE_LEN + 1];

/**
 * Make sure we have successfully read title, director, and date info
 * before we attempt to create a new movie object:
 */
if ( fgets( title, sizeof title, stdin ) && dir && d )
{
  movie *m = createMovie( title, dir, d );
}
“但是,”你说,“我想创建一个电影数组。”那么,你可以创建一个指向
movie
的指针数组,然后为每个元素分配一个新的
movie
对象:

movie **m = malloc( totalMovies * sizeof *m ); // sizeof *m == sizeof (movie *)
if ( m )
{
  for ( int i = 0; i < totalMovies; i++ )
  {
    date *d = dateFromStdInput();
    director *dir = dirFromStdInput();
    char title[MAX_TITLE_LEN+1];

    if ( fgets( title, sizeof title, stdin ) && dir && d )    
      m[i] = createMovie( title, dir, d );
  }
}
再一次,这些都是我头脑中的建议;毫无疑问,有更好的方法来构造这段代码,但无论如何,它都应该让您开始


  • 请记住,
    sizeof
    是一个运算符,而不是一个函数;仅当操作数是类型名(如
    int
    movie
    )时,才需要使用参数。添加它们并没有什么坏处
    sizeof(*movie_ptr)
    将以同样的方式工作。不过,这也节省了一些混乱。
    没有typedef结构,为什么不呢?@USER 253551我用过好几次,这对于C++和C来说是一样的:核心语言将为你做的很少。你必须完成所有的工作,并编写所有的代码来完成。C和C++都没有捷径,只需要使用它就能使所有的事情发生。如果您必须
    malloc
    几个不同的对象,并且每个对象都有指针,这些指针本身也必须依次
    malloc
    ed,那么必须编写这样做的代码。要详细说明。。。“typedef struct”不是一个术语。这是两个连续的关键词,每一个都有自己的效果。任何一方的存在都不会影响另一方的行为。所以“typedef struct”并没有传达任何有意义的东西。通常你可以使用一个函数来为你做这件事(显然你必须编写它)次要:
    if(fgets(title)&&dir&d)
    不如
    if(dir&d&&fgets(title))
    如果先前的分配失败,则不尝试输入。@chux:fixed
    fgets
    调用。我会责备睡眠不足。
    void freeMovie( movie *m )
    {
      free( m->releaseDate );
      free( m->director->name );
      free( m->director->surname );
      free( m->director );
      free( m->title );
      free( m );
    }