【问题标题】: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
  • 我可以,但这不是这里的问题!
  • 为了让我们回答而无需猜测,您至少想向我们展示所有涉及的变量是如何初始化的,以及函数是如何被调用的。您可能还想看看这里:stackoverflow.com/help/minimal-reproducible-example 就目前而言,这个问题无法认真回答。
  • SimpleCommand * tempCommand = simpleCommand;创建simpleCommand的副本。
  • 我已经尽我所能在上面添加了一个最小的可重现示例。 @user3386109

标签: c shell struct command malloc


【解决方案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 使用单个指针;而不是指向指针的指针?我需要存储许多这些简单的命令。
  • 你为指针而不是结构分配内存。请按照我的代码。
猜你喜欢
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-28
相关资源
最近更新 更多