为啥我在 c 中遇到 atoi 的段错误?

Posted

技术标签:

【中文标题】为啥我在 c 中遇到 atoi 的段错误?【英文标题】:Why do I get a segfault with atoi in c?为什么我在 c 中遇到 atoi 的段错误? 【发布时间】:2020-12-10 10:27:46 【问题描述】:

我正在尝试从 argv 读取字符串。它应该类似于 "-x^2-5" 等数学函数。

我有这样的东西:

void test(char *function)
  int temp = 0;
  for (int i = 0; i < strlen(function); i++)
    if((function[i] != '+') && (function[i] != ...)
      // function[i] is a digit, but still as a char
      temp = atoi(function[i]);
    
  
  //... 

int main(int argc, char **argv)
  test(argv[1]);
  //...

这在循环的最后一圈之前运行良好。 如果我使用printf("%c", function[i]);,它就是5

但是atoi(function[i]) 给出了段错误。为什么?

【问题讨论】:

请在使用argv[1]之前测试if(argc &gt;= 2) 打开编译器警告! function[i] 是单个 char,而不是 char*。因此,它被隐式转换为指针类型,atoi 尝试从接近零的内存地址读取。也许你的意思是&amp;function[i]function + i atoi(function[i]) 实际上是无效的 C,所以无论编译器让这段代码通过什么都是不好的。请注意,大多数主流 C 编译器默认情况下都处于“不良模式”。您必须添加 -std=c11 -pedantic-errors 才能将它们转换为 C 编译器。另请参阅“Pointer from integer/integer from pointer without a cast” issues。 【参考方案1】:

没错。我们先来看看atoi的签名。

int atoi(const char *str);

现在,您传递给它的是function[i],因为functionchar * 类型,function[i]char。而且您的角色很可能不是正确的角色指针。

您想要传递给atoi 的是const char *,您可以通过调用atoi(&amp;function[i]); 得到它

【讨论】:

@xXxKaddiexXx 虽然如果我试图解析这样的表达式,我会考虑对表达式进行“适当”的词法分析,然后使用“分流场”算法来创建一个用户提供的表达式中的表达式树。更容易识别符号是运算符、变量(如 x)还是文字值(如 2)。也更容易评估。【参考方案2】:

正如@sham1 所说,atoi 期望它的参数是一个 C 字符串,这是一个以 null 结尾的 char 数组,而您只有一个 char。

但是数字是特殊的,因为它们需要有连续的代码。所以如果你知道一个字符(比如c)是一个数字,它的值就是c - '0'。所以你可以写:

if((function[i] != '+') && (function[i] != ...)
  // function[i] is a digit, but still as a char
  temp = function[i] - '0';    // get the int value of a digit character

【讨论】:

实际上这在我的情况下不起作用。我不确定我是否错过了上面代码示例中的重要内容。【参考方案3】:

除了其他答案中指出的错误之外,atoi 没有任何可靠的错误处理,这就是为什么它是standard library functions that should never be used 之一。

忘记您曾经听说过atoi 并将其替换为:

char* endptr;
int result = strtol(str,&endptr,10);

if(endptr == str)

  // some conversion error

strtol 也可以转换字符串的初始部分,如果它包含有效数字。

【讨论】:

哦不,我不知道。那会节省很多时间xD。谢谢你:) @xXxKaddiexXx 在这种特定情况下,您实际上提供的内容不是以 null 结尾的字符串,因此 strtol 也不太可能找到这个问题。

以上是关于为啥我在 c 中遇到 atoi 的段错误?的主要内容,如果未能解决你的问题,请参考以下文章

C中多线程python扩展中的段错误

GCC 生成的程序集 - C 函数调用时的段错误

使用 CUDA 流时的段错误

文件读取期间的段错误

GCC __attribute__ 在 32 字节处对齐的 AVX 矢量化代码中的段错误

QOpenGLVertexArrayObject 导致多个 VBO 的段错误?