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

时间:2015-09-03 04:31:35

标签: c++ atoi

我已经搜索了几个小时,我似乎无法找到与此问题相关的任何内容。如果您在其他地方发现此问题,请指出我找到它的位置。

我在c ++中使用atoi(const char *)函数,一切正常......直到我尝试使用1,000,000及以上的数字。

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

int toRead = atoi(argv[2]);

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

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

int toRead = atoi('1000000');

这也崩溃了。我试过atol认为整数数据类型可能没有空间。这也行不通。我还在我的系统上运行了INT_MAX,并获得了标准的2,147,483,647,因此一个int绝对可以容纳1,000,000

然后我用这段代码继续实现了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命中它。

有人可以帮我弄清楚为什么会这样吗?

我正在使用intel 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 file\n";
        else
            cout << "\nFile opened: Ready to process " << toRead << " numbers\n\n";

        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];

5 个答案:

答案 0 :(得分:4)

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的数组。可以使用动态分配。

答案 1 :(得分:1)

以下代码使用编译器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

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

答案 2 :(得分:1)

您正在获得stack overflow,因为您正在转换数字

int toRead = atoi(argv[2]);

然后在调用堆栈上分配该大小的动态variable-length array(VLA)(BTW不是标准C ++ 11;原始数组应该具有编译时常量作为其大小,而VLA是非标准的)

int arr[toRead];

典型的呼叫大小限制在几兆字节(有时甚至更少)。根据经验,您应确保调用堆栈上的每个call frame最多只有几千字节(在当前桌面上)。

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

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

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

如果因为某些(恕我直言)的原因你被禁止使用容器,你需要在堆中分配数组

int* arr = new int[toRead];

但请勿忘记释放内存 - 以避免memory leaks - 稍后(在最后一次,甚至是间接使用arr之后),在适当的地方,

delete [] arr;

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

答案 3 :(得分:0)

int toRead = atoi(argv[2]);

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

#include <string>

int toRead = std::stoi(std::string(argv[2]));

答案 4 :(得分:-1)

也许使用boost库转换为整数,而不是:

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