如何将自定义结构插入另一个包含初始结构的二维指针的结构中?

Posted

技术标签:

【中文标题】如何将自定义结构插入另一个包含初始结构的二维指针的结构中?【英文标题】:How do I insert a custom struct into another struct that holds a 2 dimensional pointer of the initial struct? 【发布时间】:2020-03-19 19:05:43 【问题描述】:

我有两个结构,一个用于创建命令。另一个包含这些命令的 2D 指针结构。

typedef struct SimpleCommand 
    // Available space for arguments currently preallocated
    int _numberOfAvailableArguments;
    // Number of arguments
    int _numberOfArguments;
    // Array of arguments
    char *_arguments[];
SimpleCommand;

例如: 简单命令0:ls -la

现在我需要将此命令插入到该结构内的指针中,以便在第 0 行中键入简单命令。

typedef struct Command 
        int _numberOfAvailableSimpleCommands;
        int _numberOfSimpleCommands;
        SimpleCommand ** _simpleCommands;
        char * _outFile;
        char * _inputFile;
        char * _errFile;
        int _background;
        int outputAppend;
Command;

然后,我将能够构造一个新的简单命令,并将其插入到第 1 行。然后我会: 命令->simpleCommands[0] = simpleCommand 0 命令->simpleCommands[1] = simpleCommand 1

到目前为止,我能够创建并验证简单的命令是否有效。这是我尝试将一个简单命令插入到 commands->simplecommands 指针的操作:

void insertSimpleCommand(SimpleCommand * simpleCommand, Command * command )
    command->_simpleCommands = realloc(command->_simpleCommands, sizeof(simpleCommand)*3);
    SimpleCommand * tempCommand = simpleCommand;

    command->_simpleCommands[command->_numberOfSimpleCommands] = tempCommand;

    command->_numberOfSimpleCommands++; //increase the number of simple commands in the commands

当我这样做时,接下来发生的事情是旧的命令->simpleCommands[0] 被新的 simpleCommand 覆盖。我可以做些什么不同的事情,以便这些简单的命令被正确地一一添加并且之后都可以访问?

编辑: 这是我正在尝试做的最小可重复示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>

// Describes a simple command and arguments
typedef struct SimpleCommand 
    // Available space for arguments currently preallocated
    int _numberOfAvailableArguments;
    // Number of arguments
    int _numberOfArguments;
    // Array of arguments
    char *_arguments[];
SimpleCommand;

// Describes a complete command with the multiple pipes if any
// and input/output redirection if any.
typedef struct Command 
        int _numberOfAvailableSimpleCommands;
        int _numberOfSimpleCommands;
        SimpleCommand ** _simpleCommands;
        char * _outFile;
        char * _inputFile;
        char * _errFile;
        int _background;
        int outputAppend;
Command;

//FUNCTION DEFINITIONS
void insertSimpleCommand( SimpleCommand * simpleCommand, Command * command );
void insertArgument(SimpleCommand *command, char * argument );

int main(int argc, char * argv[])
    //initialize the global currentsimplecommand struct
    SimpleCommand *_currentSimpleCommand = malloc(sizeof(*_currentSimpleCommand) + sizeof(char[50]));
    _currentSimpleCommand->_numberOfArguments = 0;
    _currentSimpleCommand->_numberOfAvailableArguments = 1;
    _currentSimpleCommand->_arguments[_currentSimpleCommand->_numberOfArguments] = (char*)malloc(sizeof(char*) * 50);

    //SET UP COMMAND struct
    Command *_currentCommand = (Command*)malloc(2 * sizeof(Command));
    _currentCommand->_numberOfSimpleCommands = 0;
    _currentCommand->_background = 0;
    _currentCommand->outputAppend = 0;

    insertArgument(_currentSimpleCommand,"ls");
    insertArgument(_currentSimpleCommand,"-la");
    insertSimpleCommand(_currentSimpleCommand, _currentCommand);
    clear(_currentSimpleCommand);

    insertArgument(_currentSimpleCommand,"head");
    insertSimpleCommand(_currentSimpleCommand, _currentCommand);

    for (int i = 0; i < _currentCommand->_numberOfSimpleCommands; i++)
         printf("\n\nTEST: %d   %s\n\n", i, _currentCommand->_simpleCommands[i]->_arguments[0]);
    
    /*
        THE OUTPUT OF THIS WILL PRODUCE THE SAME ARGUMENT[0] regardless fo the row we are on!
    */


 

void insertSimpleCommand(SimpleCommand * simpleCommand, Command * command )
    command->_simpleCommands = realloc(command->_simpleCommands, sizeof(simpleCommand)* command->_numberOfSimpleCommands);
    SimpleCommand * tempCommand = simpleCommand;
    command->_simpleCommands[command->_numberOfSimpleCommands] = tempCommand;
    command->_numberOfSimpleCommands++; //increase the number of simple commands in the commands


//insert argument into simple command
void insertArgument(SimpleCommand *command, char * argument ) 
    //allocate space for the new command
    command->_arguments[command->_numberOfArguments] = (char*)realloc(command->_arguments[command->_numberOfArguments], sizeof(char*) * strlen(argument));
    strcpy(command->_arguments[command->_numberOfArguments], argument);
    command->_arguments[command->_numberOfArguments+1] = NULL;
    command->_numberOfArguments++;


//clears the simple command for the next one
void clear(SimpleCommand *command)
    free(command);
    SimpleCommand *_currentSimpleCommand = malloc(sizeof(*_currentSimpleCommand) + sizeof(char[50]));
    _currentSimpleCommand->_numberOfArguments = 0;
    _currentSimpleCommand->_numberOfAvailableArguments = 1;
    _currentSimpleCommand->_arguments[_currentSimpleCommand->_numberOfArguments] = (char*)malloc(sizeof(char*) * 50);

谢谢!

【问题讨论】:

乘以这个幻数*3的目的是什么?为什么不使用command-&gt;_numberOfSimpleCommands 我可以,但这不是这里的问题! 为了让我们回答而无需猜测,您至少想向我们展示所有涉及的变量是如何初始化的,以及函数是如何被调用的。您可能还想看看这里:***.com/help/minimal-reproducible-example 就目前而言,这个问题无法认真回答。 SimpleCommand * tempCommand = simpleCommand;创建simpleCommand的副本。 我已经尽我所能在上面添加了一个最小的可重现示例。 @user3386109 【参考方案1】:
#include <stdlib.h>
#include <string.h>

typedef struct SimpleCommand 
    int id;
    // Available space for arguments currently preallocated
    int _numberOfAvailableArguments;
    // Number of arguments
    int _numberOfArguments;
    // Array of arguments
    char *_arguments[];
SimpleCommand;

typedef struct Command 
        int _numberOfAvailableSimpleCommands;
        int _numberOfSimpleCommands;
        SimpleCommand ** _simpleCommands;
        char * _outFile;
        char * _inputFile;
        char * _errFile;
        int _background;
        int outputAppend;
Command;

void insertSimpleCommand(SimpleCommand * simpleCommand, Command * command )
    command->_simpleCommands = realloc(command->_simpleCommands, sizeof(SimpleCommand *) * command->_numberOfSimpleCommands + 1);

    SimpleCommand *newCommand = malloc(sizeof(SimpleCommand));
    memcpy(newCommand, simpleCommand, sizeof(SimpleCommand));

    command->_simpleCommands[command->_numberOfSimpleCommands] = newCommand;
    command->_numberOfSimpleCommands++; //increase the number of simple commands in the commands


void main() 

    SimpleCommand s1;
    Command c;

    c._simpleCommands = malloc(sizeof(SimpleCommand *)*1);

    s1.id = 1;

    insertSimpleCommand(&s1, &c);

    s1.id = 2;

    insertSimpleCommand(&s1, &c);

    exit(0);



(gdb) b main
Breakpoint 1 at 0x7de: file simple.c, line 40.
(gdb) r
Starting program: /tmp/s 

Breakpoint 1, main () at simple.c:40
40          c._simpleCommands = malloc(sizeof(SimpleCommand *)*1);
(gdb) n
42          s1.id = 1;
(gdb) 
44          insertSimpleCommand(&s1, &c);
(gdb) 
46          s1.id = 2;
(gdb) 
48          insertSimpleCommand(&s1, &c);
(gdb) 
50          exit(0);
(gdb) p *c->_simpleCommands[0]
$1 = id = 1, _numberOfAvailableArguments = 32767, _numberOfArguments = 0, _arguments = 0x555555756290
(gdb) p *c->_simpleCommands[1]
$2 = id = 2, _numberOfAvailableArguments = 32767, _numberOfArguments = 0, _arguments = 0x5555557562b0
(gdb) 

【讨论】:

这看起来可行。但是,我需要简单的命令才能动态增长。在您的示例代码中,它们被初始化为 s1、s2。我需要能够在整个程序中不断创建这些,并不断将它们添加到命令 ** simplecommands 中。 复制整个代码并按照我对 gdb 所做的步骤进行操作。 您是否有机会查看我在原始帖子中的最小可重现示例? @Gábor 为什么对 SimpleCommand * _simpleCommands 使用单个指针;而不是指向指针的指针?我需要存储许多这些简单的命令。 你为指针而不是结构分配内存。请按照我的代码。

以上是关于如何将自定义结构插入另一个包含初始结构的二维指针的结构中?的主要内容,如果未能解决你的问题,请参考以下文章

如何将结构中的 void 指针分配给另一个结构?

c语言赋值是啥?

python如何定义二维结构体数组?

基本数据结构—Trie

包含相同类型的结构指针的结构指针的初始化

C 语言二级指针作为输入 ( 二维数组 | 二维数组遍历 | 二维数组排序 )