【问题标题】:Is this the right way to allocate memory?这是分配内存的正确方法吗?
【发布时间】:2019-02-11 07:05:46
【问题描述】:

我在某人的代码中遇到了这个...我不知道它是否正确(因为即使它看起来不对,它也可以工作)。有人可以澄清这是否正确,为什么是这样,以及为什么它仍然有效?


简而言之,我们希望将所有参数(以命令行形式给出)串联存储在 1 个字符串中。

注意:每个字符串至少有 1 个字符。


片段:

int main(int argc, char **argv) {

    // Declaring a pointer to a string
    char *desintation_string;

    // Allocating enough memory to store all arguments (given as command-line) concatenated 
    destination_string = malloc((argc) * sizeof(char));   /* <————— is this correct ? does 
                                                                    it indeed allocate
                                                                    enough memory to fit
                                                                    all the arguments
                                                                    concatenated ? */
    . . . 
}

问题是:

这行“destination_string = malloc((argc) * sizeof(char));”是否为此分配了足够的内存?

有人能解释一下这是做什么的吗?因为我把它读为:它正在分配(argc * 1 字节)。然而,当您运行它并将参数复制到它时,它会起作用,有人可以解释一下吗?

【问题讨论】:

  • 只要您收到的每个字符串都有一个字符!
  • @CinCout .. 这不分配(argc * 1 字节)...如何存储所有参数的所有字符就足够了?还是我的假设错了?
  • @Lion 它完全按照你的想法做。
  • 代码错误。阅读how to debug small programs。也可以使用valgrind
  • 好的,谢谢.. 所以这是错误的。只是必须确保。

标签: c string malloc command-line-arguments allocation


【解决方案1】:

这行是否“destination_string = malloc((argc) * sizeof(char));” 分配足够的内存吗?

。您需要分配足够的内存。例如这里

#define BUFSIZE YOUR_EXPECTED_SIZE

destination_string = malloc((BUFSIZE) * sizeof(char));

例如命令行:a.out foo bar

snprintf(foo, 1024, "%s - %s\n", argv[1], argv[2]);

【讨论】:

  • 谁说1024就够了?
  • @immibis 我知道,但这只是示例目的。
  • 是的,每次都不一样……可能超过 1024,谁知道呢。
  • 这不是“唯一的例子”,这个问题的整点是多少才足够。如果问题是关于其他的,那么你可以以 1024 为例,并说读者可以用更好的东西来代替它,但这个问题部分是关于 1024 的。
【解决方案2】:

没有。假设你的论点是"foo" "bar"。这使得argc = 2。在这种情况下,使用 malloc((argc) * sizeof(char)) 您只为 2 个字符分配内存。

argv 是一个二维数组(因此是argv**)。您需要检查每个参数拳头的长度以便为它们分配内存。


malloc((argc) * sizeof(char)) 做了什么: argc 是您传递的参数数量。 sizeof(char) 返回需要为 char 变量分配的字节数。所以你得到malloc(&lt;number of bytes needed to store argc number of char variables&gt;)malloc() 在堆中分配该数量的字节。

【讨论】:

  • 啊,这就是我的想法……这很奇怪,因为当您尝试复制 dest_str 中的参数时它可以工作,即使是这样。任何想法为什么?
  • 这可能有效,但不安全。可能会起作用,因为目前任何其他程序都没有使用分配的内存旁边的内存地址。但是,如果某些东西开始使用该内存,则该数据将在运行时丢失,因为它是操作系统看到的空闲内存。
  • @Lion 当malloc 被调用时,它返回一个指针,指向至少所请求的内存,但是对于小分配,实际的内存块通常很多大于请求的大小。因此,即使使用比请求更多的内存总是一个坏主意,也不一定会导致立即崩溃。
  • @user3386109 谢谢你的解释。现在一切都清楚了。
  • @TeshanShanukaJ 在几乎任何现代操作系统上,您的程序都存在于自己的虚拟地址空间中,因此您无法通过写入内存来破坏其他程序的数据。然而,可能 发生的情况是,您可能会覆盖堆用于必要簿记的数据结构,或者堆可能已提供给程序另一部分的下一个内存块。顺便说一句,sizeof(char) 的定义是 1,因为sizeofchar 为单位返回大小。
【解决方案3】:

您的代码仅适用于短类型的参数(即-x)。但是对于长类型的参数(即--list),它会失败。

你可以这样做。

int main(int argc, char **argv) {

    // Declaring a pointer to a string.
    char *desintation_string;
    int Arg_Size = 0;

    // Allocating enough memory to store all arguments concatenated.
    // argv[0] is path not argument given in command line
    for (int i=1, i <= argc, i++)
        Arg_Size += sizeof(argv[i]);

    destination_string = malloc(Arg_Size); 
    . . . 
}

【讨论】:

    猜你喜欢
    • 2018-09-19
    • 2011-01-13
    • 2012-01-22
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    相关资源
    最近更新 更多