【问题标题】:Why is atoi giving me a segmentation fault?为什么 atoi 给我一个分段错误?
【发布时间】:2010-11-05 17:13:12
【问题描述】:

我有以下代码:

#include <stdio.h>

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

    M = 1;
    N = 1;
    curr = 1;

    if ( argv[1][0] == '-' )
    {
        curr = 2;

        char *a = argv[1][1];
        char *b = argv[1][3];

        M = atoi(a);
        N = atoi(b);
    }

    printf("%d\n%d", M, N);
}

所以,我通过这个程序是这样的:

a.out -1,2

而不是得到预期的输出

1
2

我遇到了分段错误。什么给了?

【问题讨论】:

  • 您使用的是什么损坏的编译器? char *a = argv[1][1]; 应该给出编译器错误。 C 没有从 int 到指针类型的隐式转换。

标签: c segmentation-fault atoi


【解决方案1】:

编译?!

char argv*[] 是一个 char 指针数组。

char *a = argv[1][1]

  • 获取第二个字符指针,所以现在你有一个char *
  • 获取该指针中的第二个元素,它将是一个字符。

所以现在你将一个 char 分配给一个 char 指针(这应该是一个编译错误)。

我只能假设您的意思是说char *a = &amp;argv[1][1]。顺便说一句,常量正确性也很好,所以const char *a = &amp;argv[1][1]

顺便说一句,你的代码仍然很不安全——你甚至没有检查字符串的大小。想象一下,如果你的字符串只有两个字符,&amp;argv[1][3] 会做什么。

【讨论】:

  • 没有头文件的默认假设是函数在调用时存在(隐式声明)并返回一个int。这是一个很好的论据,可以将警告作为编译器上的错误和高警告设置。
  • 这与函数无关,而是将char 分配给char *
  • 我以为他的意思是 char *a = argv[1] + 1;&amp;(argv[1][1]);
【解决方案2】:

#include &lt;stdlib.h&gt; 应该会很明显。

详细说明:您将整数传递给需要指针的函数,编译器无法警告您,因为您忘记使用原型声明函数。这就是崩溃的原因。

此外,您只是在滥用atoiatoi 解析字符串,而不是单个字符。如果要将字符的值作为数字,只需减去'0'

M = argv[1][1]-'0';
N = argv[1][3]-'0';

在实践中,您还应该检查该字符实际上是一个数字。

编辑:我不记得 char *a = argv[1][1]; 出现在原始帖子中(可能早期的编辑不会显示为编辑?),但任何理智的编译器都应该给出编译时错误在那条线上。整数不会隐式转换为 C 中的指针。如果编译器允许这样做,那么包含 atoi 的原型将不再有帮助,因为类型错误发生得更早。

【讨论】:

  • 我自己也看到了问题的神奇变化,而没有将它们标记为已编辑。诡异。
【解决方案3】:

atoi 接受一个字符串,而不是一个字符。

另外,atoi 总体来说不是很好,因为它基本上没有错误报告。在大多数情况下,您应该调查 strtol。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多