我已经搜索了几个小时,我似乎无法找到与此问题相关的任何内容。如果您在其他地方发现此问题,请指出我找到它的位置。
我在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];
答案 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