【问题标题】:How do I dynamically allocate multiple strings from the command line argv?如何从命令行 argv 动态分配多个字符串?
【发布时间】:2022-01-06 19:53:59
【问题描述】:

对于这个任务,我应该从命令行参数中获取多个名称,这些名称以'+'(将名称插入我的链接列表)或'-'(从列表中删除名称)开头,所以如果我输入“+bill +jim +ted -bill”,我将添加这三个不带“+”的名称并删除账单。我尝试使用malloc 动态分配一个字符串,这样我就可以修改name 字符串,但是我的代码没有将字符串数据插入到我的链表中,当我通过一些时我得到一个 free(): invalid pointer 错误测试字符串。如果我将 free(name) 语句移动到 if/else if 语句中,我会遇到分段错误。我将如何从命令行正确地动态分配这些字符串以便可以修改它们?

int main(int argc, char *argv[]){
    struct node* head;
    for(int x = 0; x < argc; x++){
            char * name = malloc((strlen(argv[x])+1));
            name = argv[x];
            if(name[0] == '+'){
                    printf("adding %s \n", name++);
                    insert(&head, name++);
                    printf("List: ");
                    printList(&head);
            }
            else if(name[0] == '-'){
                    printf("removing %s \n", name++);
                    removeNode(&head, name++);
            }
            free(name);
    }
}

char * removeNode(struct node** head, char* name){
        struct node *current = *head;
        struct node *previous;

        if(current == NULL){
                return "error0";
        }

        if(current->data == name){
                struct node * node2delete= *head;
                *head = node2delete->next;
                char * name2 = malloc(strlen(name)+1);
                strcpy(name2, name);
                free(node2delete);
                printf("Removed %s \n", name);
                return name2;
        }
        while(current != NULL){
                previous  = current;
                current = current->next;
                if(current->data == name){
                        previous->next = current->next;
                        char * name2 = malloc(strlen(name)+1);
                        strcpy(name2, name);
                        free(current);
                        printf("Removed %s \n", name);
                        return name2;
                }
        }
        return "error0";
}

【问题讨论】:

    标签: c string argv argc


    【解决方案1】:

    尝试使用strcpy(name, argv[x]); 而不是name = argv[x],因为当您将指针分配给指针时,它们将指向存储空终止字符数组的相同内存位置。这样您就可以在调用 free(name); 时为 argv[x] 完成内存释放;

    指针操作与赋值不同。

    也可以看到这个帖子:How do malloc() and free() work?

    【讨论】:

      【解决方案2】:

      很多问题

      字符串复制不正确

          //char * name = malloc((strlen(argv[x])+1));
          //name = argv[x];
          char * name = malloc(strlen(argv[x])+1);
          if (name == NULL) return EXIT_FAILURE; // Out of memory
          strcpy(name, argv[x]);
      

      不正确的free()

      代码需要释放从分配中收到的相同值。 name++ 搞砸了。

      头部未初始化*

      // struct node* head;
      struct node* head == NULL;
      

      更多

      可能只需要在+/-之后添加和分配时才需要分配。

      int main(int argc, char *argv[]){
        struct node* head = NULL;
        // for(int x = 0; x < argc; x++){
        for(int x = 1; x < argc; x++){  // Skip adding the program name, start at 1
          if(argv[x][0] == '+'){
            char * name = malloc((strlen(argv[x] + 1)+1));
            if (name == NULL) return EXIT_FAILURE; // Out of memory
            strcpy(name, argv[x]);
            printf("adding %s \n", name);  // No ++
            insert(&head, name); // No ++
            printf("List: ");
            printList(&head);
          }
          else if(argv[x][0] == '-'){
            printf("removing %s \n", argv[x] + 1);
            // This is a problem, I'd expect removeNode() to return a pointer to the free'd name
            char *name = removeNode(&head, argv[x] + 1);
            free(name);
          }
        }
      

      【讨论】:

      • 如何返回指向已释放内存的指针?我需要使用 malloc 和 strcpy 来返回指向我删除的节点的指针吗?
      • @TorinCostales 不要返回指向已释放内存的指针。相反,让char *removeNode() 返回一个指针,调用代码稍后将释放该指针。 removeNode()可以删除节点,但不应该删除它保存的字符串指针。很大程度上取决于removeNode()的细节,由于没有显示,只能进行表面讨论。
      • 所以我正在研究这个功能,现在它显示出来了。我尝试动态分配将返回的另一个字符串,但它仍然会导致分段错误。我试图只返回参数 {name},但这也是另一个分段错误。返回指针的正确方法是什么?我是动态记忆的新手,这让我头晕目眩
      • 我希望像 if(strcmp(current-&gt;data, name) == 0){ char *data = current-&gt;data; previous-&gt;next = current-&gt;next; free(current); printf("Removed &lt;%s&gt; \n", data); return data; } 这样的东西。然而,这取决于看不见的insert()。对不起,没有时间更多了。祝你好运。
      猜你喜欢
      • 1970-01-01
      • 2022-01-02
      • 2016-04-16
      • 2016-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-15
      • 1970-01-01
      相关资源
      最近更新 更多