c++atoi在100万及以上时崩溃

c++ atoi crashes at 1 million and above

本文关键字:崩溃 100万 c++atoi      更新时间:2023-10-16

我已经搜索了几个小时,似乎找不到任何与这个问题相关的东西。如果你在其他地方发现了这个问题,请告诉我你在哪里发现的。

我在c++中使用atoi(const char *)函数,一切都很好。。。。直到我尝试使用1000000及以上的数字。

这就是我的程序崩溃的地方:

int toRead = atoi(argv[2]);

此代码适用于10、100、1000、10000等…直到100万。然后我得到一个Windows错误,Main.exe已经停止工作,它问我是否要调试。

我已经硬编码了相同的代码来检查

int toRead = atoi('1000000');

这也会崩溃。我尝试过atol,认为整数数据类型中可能没有空间。这也不起作用。我还在我的系统上运行了INT_MAX,得到了标准的2147483647,所以一个INT绝对可以容纳1000000个

然后,我用以下代码自己实现了atoi方法:

int atoi( const char *c ) 
{
  int value = 0;
  int sign = 1;
  if( *c == '+' || *c == '-' )
  {
     if( *c == '-' ) sign = -1;
     c++;
  }
  while ( isdigit( *c ) )
  {
     value *= 10;
     value += (int) (*c-'0');
     c++;
  }
  return value * sign;
}

这段代码的工作原理和atoi方法一样,因为它工作得很好,直到我达到1000000。

有人能帮我弄清楚为什么会发生这种事吗?

我在一个不错的台式机上运行英特尔i7四核,16GB内存,所以我不认为这是机器问题。

任何帮助都将不胜感激。

谢谢!

这是我的全部代码:

#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <sstream>
#include <ctime>
#include <limits.h>
int main(int argc, char* argv[]) {
    if (argc != 3)
        cout << "nUsage: " << argv[0] << " <filename> <# of elements to process>" << endl;
    else
    {
        int toRead = atoi(argv[2]);
        int arr[toRead];
        ifstream file(argv[1]);
        if (!file.is_open())
            cout << "nCould not open filen";
        else
            cout << "nFile opened: Ready to process " << toRead << " numbersnn";
        string nums;
        int numi;
        for (int i = 0; i < toRead; i++)
        {
            getline(file, nums);
            stringstream ss(nums);
            ss >> numi;
            arr[i] = numi;
        }
        // Find minimum number
        int min = arr[0];
        time_t startTime = time(NULL);
        for (int i = 1; i < toRead; i++)
        {
            if (arr[i] < min)
                min = arr[i];
        }
        time_t timePassed = time(NULL) - startTime;
        cout << "Minimum value: " << min << endl
                << "Elapsed time: " << timePassed << endl;
        file.close();
    }
    return 0;
}

***正如我的amyCU所指出的,错误在于1000000的数组分配。谢谢你的帮助。我觉得自己像个白痴。

编辑

这解决了这个问题:

int* arr = new int[toRead];
int toRead = atoi('1000000')

使用双引号" "

int toRead = atoi("1000000");

查看atoi期望的参数-

int atoi (const char * str);  // a const string (Null Terminated)

编辑

你看到的崩溃可能是因为这个-

int arr[toRead];  // toRead= 1 million

具有自动存储和元素数1 million的阵列。可能使用动态分配。

以下代码使用编译器Visual Studio 2013 Ultimate:在我的Windows 7计算机上编译并运行良好

int xatoi(const char *c)
{
    int value = 0;
    int sign = 1;
    if (*c == '+' || *c == '-')
    {
        if (*c == '-') sign = -1;
        c++;
    }
    while (isdigit(*c))
    {
        value *= 10;
        value += (int)(*c - '0');
        c++;
    }
    return value * sign;
}
void so()
{
    char *p = "100000000";
    int i = atoi(p);
    cout << i << endl;
    i = xatoi(p);
    cout << i << endl;
}
int main(int argc, char *argv[])
{
    so();
    int toRead = atoi(argv[1]);
    cout << toRead << endl;
    return 0;
}

注意:您需要从命令提示符下运行它,并将有效数字作为第二个参数(argv[1](传递。我已经测试了100000000

请将其与您自己的实现进行比较。

由于您正在转换一个数字,因此会出现堆栈溢出

int toRead = atoi(argv[2]);

然后在调用堆栈上分配一个该大小的动态可变长度数组(VLA((BTW不是标准的C++11;原始数组的大小应该有编译时间常数,VLA是非标准的(

int arr[toRead];

一个典型的调用大小被限制为几兆字节(有时甚至更小(。根据经验,您应该确保调用堆栈上的每个调用帧(在当前桌面上(最多只有几千字节。

解决方案可能是使用一些标准容器,例如

std::vector<int> arr(toRead);

容器的实际数据通常是堆分配的。

如果由于某些原因(IMHO错误(,您被禁止使用容器,则需要在堆中分配数组

int* arr = new int[toRead];

但不要忘记稍后(在最后一次甚至间接使用arr之后(在适当的地方使用释放内存,以避免内存泄漏

delete [] arr;

编译带有所有警告的程序&调试信息(g++ -Wall -Wextra -g(,然后在调试器(gdb(下运行它就足以找到错误。使用valgrind可能也有帮助。。调试完代码后,为了进行基准测试,请要求编译器进行优化,例如g++ -Wall -Wextra -O -g(由于GCC能够在优化时发出调试信息,因此可以同时拥有-O&-g(。您甚至可以将-O(与-O1相同(替换为-O2-O3,以要求编译器进行更多优化。

int toRead = atoi(argv[2]);

不应该崩溃。但是,您可以尝试使用std::stoi(C++转换字符串的方法(

#include <string>
int toRead = std::stoi(std::string(argv[2]));

也许可以使用boost库转换为integer,而不是:

int iValue;
try {
    iValue = boost::lexical_cast<int>(strValue);
} catch (boost::bad_lexical_cast e) {
  // do some error message, or such
}

http://www.boost.org/doc/libs/1_59_0/doc/html/boost_lexical_cast.html