【问题标题】:What's wrong with that code? (copying argv[] to array of ints)那个代码有什么问题? (将 argv[] 复制到整数数组)
【发布时间】:2015-05-31 13:59:05
【问题描述】:
    #include <cstdlib>
    #include <cstdio>

    main( int argc, char **argv ) 
    {
            int *stack = new int[argc];
            int it = 0;

            while (--argc > 0 )
            {
                    *(++stack) = atoi(*++argv);     
                    printf( "%d \t %d \n", ++it, *stack );
            }

            delete stack;                   
            return 0;
    }

stack[3] 应该包含来自argv[3] 的整数值,但它没有。

此外,我在与删除运算符munmap_chunk(): invalid pointer 连接时遇到错误

【问题讨论】:

  • delete 在 C 中不是一个东西。
  • 为什么不使用简单的传统 for 循环(例如 for (int i = 0; i &lt; argc; i++) { ... })来让代码更易于阅读,而不是在每个循环中内联处理 三个 变量迭代?
  • 您调用delete 的指针与new 返回的指针不同。因此,您的程序表现出未定义的行为。此外,以new 的数组形式分配的内存应以delete 的数组形式释放,如delete[] pointerAllocatedByNew;
  • 你也永远不会分配stack[0]。但是如果argc &gt; 3 那么stack[3] 将包含atoi(argv[3])。如果您仍然遇到问题,请发布显示问题的命令行

标签: c++ arrays argv copying


【解决方案1】:

这段代码不是 C;它是 C++。有两种选择:

  • 将代码编译为 C++,或者提出/更改您的问题以改为针对 C++ 受众。希望他们抱怨您使用printf...
  • 将代码转换为C,这很容易。将&lt;cstdlib&gt; 更改为&lt;stdlib.h&gt;,将&lt;cstdio&gt; 更改为&lt;stdio.h&gt;,将new int[argc] 更改为malloc(argc * sizeof *stack);,将delete stack; 更改为free(stack);

无论您采取哪种方式,此代码都会调用未定义的行为;它访问stack 越界,并留下stack 的第一个元素未初始化,我确信这不是我们想要的。您可能打算在读取它们之后并在递增 stack 之前打印这些值,但由于您弄错了,您正在打印您当然尚未分配的数组中的下一个元素...

然后,最重要的是,您的循环会修改 stack 的值(毕竟这是 ++stack 所做的),因此当您使用 delete 时,您的循环之后是 deleteing不是使用new 创建的引用...您需要确保保留stack 的原始值,即deleted 或freed 或其他...

#include <stdlib.h>
#include <stdio.h>

int
main( int argc, char **argv ) {
        int *stack = malloc(argc * sizeof *stack);
        int it = 0;
        while (--argc > 0){
                stack[it] = atoi(*++argv);
                printf("%d \t %d \n", it, stack[it]);
                it++;
        }
        free(stack);
        return 0;
}

【讨论】:

  • 你改变了循环逻辑;在原始的stack[0] 中没有分配,stack[1] 得到了argv[1] 等。无论哪种方式,我都建议使用it 而不是递增和递减运算符
  • @MattMcNabb 嗯,是的,我改变了逻辑,使它不会离开 stack[0] 未初始化(正如我在之前的描述中提到的那样),因此它不会尝试访问stack 越界(前面也提到过)...我得到了接受的答案,表明这种逻辑变化确实修复了某事。有问题吗?
  • 感谢大家的回复。因为它将是一个 ONP calc main() 函数实际上也应该读取和识别基本运算符 + - * /
【解决方案2】:

如果您使用数组索引而不是推进指针,您的代码会更清晰(和正确):

#include <cstdlib>
#include <cstdio>

using namespace std;

main( int argc, char **argv ) 
{
    int *stack = new int[argc];
    for( int it = 1; it < argc; ++it )
    {
        stack[it] = atoi(argv[it]);     
        printf( "%d \t %d \n", it, stack[it] );
    }

    delete[] stack;                   
    return 0;
}

不过,不知道为什么要使用未使用的 stack[0]

【讨论】:

  • 谢谢,真的很有用。
猜你喜欢
  • 2021-10-06
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多