为什么使用atoi命令行参数进行分段错误

时间:2015-09-18 11:13:40

标签: c

我需要传递两个命令行参数,我尝试了以下内容:

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

void power(int base, int exp){

    int res=1;

    while(exp!=0){
       res *= base;
        --exp;
    }

    printf("Res = %d",res);
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage %s arg2 arg2\n(EG: %s 2 3)\n",argv[0],argv[0]);
        exit(1);
    }else{
        power(atoi(argv[1]),atoi(argv[2]));
    }

    printf("\n");
    return 0;
}

输出:

michi@michi-laptop:~$ ./power
Usage ./power arg2 arg2
(EG: ./power 2 3)
michi@michi-laptop:~$ ./power 2 3
Res = 8

直到这里的所有内容都可以,但是如果在变量中保存 argv [1] argv [2] ,就像这样:

int base = atoi(argv[1]);
int exp = atoi(argv[2]);

我得到分段错误

代码:

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

void power(int base, int exp){

    int res=1;

    while(exp!=0){
       res *= base;
        --exp;
    }

    printf("Res = %d",res);
}

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

    int base = atoi(argv[1]);
    int exp = atoi(argv[2]);

    if (argc != 3) {
        printf("Usage %s arg2 arg2\n(EG: %s 2 3)\n",argv[0],argv[0]);
        exit(1);
    }else{
        power(base, exp);
    }

    printf("\n");
    return 0;
}

但是当我在printf中使用Atoi时,一切都还可以:

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

void power(int base, int exp){

    int res=1;

    while(exp!=0){
       res *= base;
        --exp;
    }

    printf("Res = %d",res);
}

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

    if (argc != 3) {
        printf("Usage %s arg2 arg2\n(EG: %s 2 3)\n",argv[0],argv[0]);
        exit(1);
    }else{
        power(atoi(argv[1]), atoi(argv[2]));
    }

    printf("\n");
    return 0;
}

我的问题是:

这个问题是因为Atoi而发生的吗?

发生此问题是因为我尝试访问 argv [1] argv [2] ,当我输入 ./ program <时,它们不存在/强>

如果我输入 ./ program 2 3 一切正常,这让我觉得发生了分段错误,因为我试图访问一个当时不属于我的内存位置

3 个答案:

答案 0 :(得分:4)

  

这个问题发生了,因为我尝试访问argv [1]和argv [2],当我输入./program时它们不存在?

是的,问题是您在验证命令行是否存在之前尝试访问命令行arg。

在第二个示例代码段中,仅在确保输入可用后才将值分配给变量baseexp

int base;
int exp;

if (argc != 3) {
    printf("Usage %s arg2 arg2\n(EG: %s 2 3)\n",argv[0],argv[0]);
    exit(1);
}else{
    /* Assign the values here, as it is verified that arg's are obtained from cmd line*/
    base = atoi(argv[1]);
    exp = atoi(argv[2]);
    power(base, exp);
}

在上面的程序中,只有在执行程序时它们作为命令行参数传递时,才能确保引用args(argv[1]argv[2])。

答案 1 :(得分:2)

  

这个问题发生了,因为我试图访问argv [1]和argv [2]和   当我输入./program?

时它们不存在

这是因为你没有检查null。如果没有传入参数,argv [1]和argv [2]可以为null。这会导致分段错误。

<iframe id="video" width="560" height="315" src="https://www.youtube.com/embed/2mWaqsC3U7k" frameborder="0" allowfullscreen></iframe>

相反,试试这个

int base = atoi(argv[1]);
int exp = atoi(argv[2]);

或者您可以检查参数计数以确保传入2个参数。

int base = 0;
int exp  = 0;

if(argv[1] && argv[2])
{
  int base = atoi(argv[1]);
  int exp = atoi(argv[2]);
}

答案 2 :(得分:1)

当您在atoi上没有参数时调用argv[ > 0]时,您正在访问超出范围内存,即未定义行为

根据C Standard定义,访问越界内存是Undefined Behavior

你可能会感兴趣