Closed. This question is off-topic。它当前不接受答案。 想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。 2年前关闭。 创建多线程程序时遇到错误。使用gdb进行调试时,atoi函数会引发错误。请帮助,atoi多线程是否不安全?如果是,替代方法是什么? 最佳答案 实现atoi()的替换非常容易:int strToInt(const char *text){ int n = 0, sign = 1; switch (*text) { case '-': sign = -1; case '+': ++text; } for (; isdigit(*text); ++text) n *= 10, n += *text - '0'; return n * sign;}(关于ideone的演示)替换已经可用的东西似乎没有多大意义。因此,我想提一些关于此的想法。可以根据具体的个人要求调整实现:可能会添加整数溢出检查可能会返回text的最终值(与strtol()相同),以检查已处理了多少个字符或进一步解析了其他内容unsigned可以使用变体(不接受符号)。前面的空格可能会也可能不会被接受可以考虑使用特殊语法还有其他一切超越了我的想象力。将此想法扩展到其他数字类型,例如float或double,它变得更加有趣。由于浮点数绝对是本地化的主题,因此必须予以考虑。 (关于十进制整数,我不确定可以本地化什么,但是即使是这种情况也是如此。)如果实现了具有浮点数语法(例如C语言)的文本文件阅读器,您可能不会忘记将语言环境调整为,然后再使用C(使用strtod())。 (作为德国人,我对这个话题很敏感,就像在德国语言环境中一样,“。”和“,”的含义反之亦然,就像英语一样。){ const char *localeOld = setlocale(LC_ALL, "C"); value = strtod(text); setlocale(LC_ALL, localeOld);}另一个事实是,考虑语言环境(即使调整为C)似乎也有些昂贵。几年前,我们实现了自己的浮点读取器来代替setlocale(),它在COLLADA读取器(一种XML文件格式,其中文件经常提供大量浮点数)中提供了60 ... 100的加速。 。更新:受到保罗·弗洛伊德(Paul Floyd)的反馈的鼓舞,我很好奇strtod()可能更快。因此,我建立了一个简单的测试套件并进行了一些测量:#include <assert.h>#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <time.h>int strToInt(const char *text){ int n = 0, sign = 1; switch (*text) { case '-': sign = -1; case '+': ++text; } for (; isdigit(*text); ++text) n *= 10, n += *text - '0'; return n * sign;}int main(int argc, char **argv){ int n = 10000000; /* default number of measurements */ /* read command line options */ if (argc > 1) n = atoi(argv[1]); if (n <= 0) return 1; /* ERROR */ /* build samples */ assert(sizeof(int) <= 8); /* May be, I want to do it again 20 years ago. */ /* 24 characters should be capable to hold any decimal for int * (upto 64 bit) */ char (*samples)[24] = malloc(n * 24 * sizeof(char)); if (!samples) { printf("ERROR: Cannot allocate samples!\n" "(Out of memory.)\n"); return 1; } for (int i = 0; i < n; ++i) sprintf(samples[i], "%d", i - (i & 1) * n); /* assert correct results, ensure fair caching, pre-heat CPU */ int *retAToI = malloc(n * sizeof(int)); if (!retAToI) { printf("ERROR: Cannot allocate result array for atoi()!\n" "(Out of memory.)\n"); return 1; } int *retStrToInt = malloc(n * sizeof(int)); if (!retStrToInt) { printf("ERROR: Cannot allocate result array for strToInt()!\n" "(Out of memory.)\n"); return 1; } int nErrors = 0; for (int i = 0; i < n; ++i) { retAToI[i] = atoi(samples[i]); retStrToInt[i] = strToInt(samples[i]); if (retAToI[i] != retStrToInt[i]) { printf("ERROR: atoi(\"%s\"): %d, strToInt(\"%s\"): %d!\n", samples[i], retAToI[i], samples[i], retStrToInt[i]); ++nErrors; } } if (nErrors) { printf("%d ERRORs found!", nErrors); return 2; } /* do measurements */ enum { nTries = 10 }; time_t tTbl[nTries][2]; for (int i = 0; i < nTries; ++i) { printf("Measurement %d:\n", i + 1); { time_t t0 = clock(); for (int i = 0; i < n; ++i) retAToI[i] = atoi(samples[i]); tTbl[i][0] = clock() - t0; } { time_t t0 = clock(); for (int i = 0; i < n; ++i) retStrToInt[i] = strToInt(samples[i]); tTbl[i][1] = clock() - t0; } /* assert correct results (and prevent that measurement is optimized away) */ for (int i = 0; i < n; ++i) if (retAToI[i] != retStrToInt[i]) return 3; } /* report */ printf("Report:\n"); printf("%20s|%20s\n", "atoi() ", "strToInt() "); printf("--------------------+--------------------\n"); double tAvg[2] = { 0.0, 0.0 }; const char *sep = "|\n"; for (int i = 0; i < nTries; ++i) { for (int j = 0; j < 2; ++j) { double t = (double)tTbl[i][j] / CLOCKS_PER_SEC; printf("%19.3f %c", t, sep[j]); tAvg[j] += t; } } printf("--------------------+--------------------\n"); for (int j = 0; j < 2; ++j) printf("%19.3f %c", tAvg[j] / nTries, sep[j]); /* done */ return 0;}我在某些平台上尝试过。Windows 10(64位)上的VS2013,发布模式:Report: atoi() | strToInt()--------------------+-------------------- 0.232 | 0.200 0.310 | 0.240 0.253 | 0.199 0.231 | 0.201 0.232 | 0.253 0.247 | 0.201 0.238 | 0.201 0.247 | 0.223 0.248 | 0.200 0.249 | 0.200--------------------+-------------------- 0.249 | 0.212cygwin,Windows 10(64位),strToInt()上的gcc 5.4.0:Report: atoi() | strToInt()--------------------+-------------------- 0.360 | 0.312 0.391 | 0.250 0.360 | 0.328 0.391 | 0.312 0.375 | 0.281 0.359 | 0.282 0.375 | 0.297 0.391 | 0.250 0.359 | 0.297 0.406 | 0.281--------------------+-------------------- 0.377 | 0.289样本已在codingground上载并执行Linux 3.10.0-327.36.3.el7.x86_64上的gcc 4.8.5,gcc -std=c11 -O2:Report: atoi() | strToInt()--------------------+-------------------- 1.080 | 0.750 1.000 | 0.780 0.980 | 0.770 1.010 | 0.770 1.000 | 0.770 1.010 | 0.780 1.010 | 0.780 1.010 | 0.770 1.020 | 0.780 1.020 | 0.780--------------------+-------------------- 1.014 | 0.773好吧,gcc -std=c11 -O2快一点。 (没有strToInt()时,它甚至比-O2慢,但标准库也可能已优化。)注意:由于时间测量涉及分配和循环操作,因此可以定性地说明哪个速度更快。它没有提供量化因素。 (要得到一个,测量将变得更加复杂。)由于atoi()的简单性,应用程序必须经常使用它,直到变得什至值得考虑开发工作时为止。关于c - atoi多线程安全吗? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44563033/ 10-13 07:40