这个指针 return 安全吗?
Is this pointer return safe?
几天前我想找到一个安全的替代 atoi
并找到以下代码作为对 this SO 问题的回应:
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef enum {
STR2INT_SUCCESS,
STR2INT_OVERFLOW,
STR2INT_UNDERFLOW,
STR2INT_INCONVERTIBLE
} str2int_errno;
str2int_errno str2int(int *out, char *s, int base) {
char *end;
if (s[0] == '[=11=]' || isspace(s[0]))
return STR2INT_INCONVERTIBLE;
errno = 0;
long l = strtol(s, &end, base);
/* Both checks are needed because INT_MAX == LONG_MAX is possible. */
if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
return STR2INT_OVERFLOW;
if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
return STR2INT_UNDERFLOW;
if (*end != '[=11=]')
return STR2INT_INCONVERTIBLE;
*out = l;
return STR2INT_SUCCESS;
}
int main(void) {
int i;
/* Lazy to calculate this size properly. */
char s[256];
/* Simple case. */
assert(str2int(&i, "11", 10) == STR2INT_SUCCESS);
assert(i == 11);
printf("%i", i);
/* Negative number . */
assert(str2int(&i, "-11", 10) == STR2INT_SUCCESS);
assert(i == -11);
}
Original code source
因为 out 指针设置为已在函数中本地定义的变量,这不是不安全吗?
这是否意味着一旦转换完成并且局部变量超出范围,它可能会被覆盖并且我们不能再依赖该值了?
我可能只是遗漏了一些东西,但目前我不明白这是一种安全的处理方式。
*out = l;
不设置 out
,它设置 *out
。也就是说,无论 out
已经指向什么,因为它 取消引用 指针。只要传入有效地址,函数就会修改一个non-local对象。
参数out
是一个指针,指向main
中的变量i
。当您稍后执行此操作时:
*out = l;
这不会更改 out
但 取消引用 它并更改它指向的变量,即 main
中的 i
。所以当函数returns修改为i
.
如果out
指向str2int
中的局部变量,那么你就会遇到指针指向无效内存的问题。
几天前我想找到一个安全的替代 atoi
并找到以下代码作为对 this SO 问题的回应:
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef enum {
STR2INT_SUCCESS,
STR2INT_OVERFLOW,
STR2INT_UNDERFLOW,
STR2INT_INCONVERTIBLE
} str2int_errno;
str2int_errno str2int(int *out, char *s, int base) {
char *end;
if (s[0] == '[=11=]' || isspace(s[0]))
return STR2INT_INCONVERTIBLE;
errno = 0;
long l = strtol(s, &end, base);
/* Both checks are needed because INT_MAX == LONG_MAX is possible. */
if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
return STR2INT_OVERFLOW;
if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
return STR2INT_UNDERFLOW;
if (*end != '[=11=]')
return STR2INT_INCONVERTIBLE;
*out = l;
return STR2INT_SUCCESS;
}
int main(void) {
int i;
/* Lazy to calculate this size properly. */
char s[256];
/* Simple case. */
assert(str2int(&i, "11", 10) == STR2INT_SUCCESS);
assert(i == 11);
printf("%i", i);
/* Negative number . */
assert(str2int(&i, "-11", 10) == STR2INT_SUCCESS);
assert(i == -11);
}
Original code source
因为 out 指针设置为已在函数中本地定义的变量,这不是不安全吗?
这是否意味着一旦转换完成并且局部变量超出范围,它可能会被覆盖并且我们不能再依赖该值了?
我可能只是遗漏了一些东西,但目前我不明白这是一种安全的处理方式。
*out = l;
不设置 out
,它设置 *out
。也就是说,无论 out
已经指向什么,因为它 取消引用 指针。只要传入有效地址,函数就会修改一个non-local对象。
参数out
是一个指针,指向main
中的变量i
。当您稍后执行此操作时:
*out = l;
这不会更改 out
但 取消引用 它并更改它指向的变量,即 main
中的 i
。所以当函数returns修改为i
.
如果out
指向str2int
中的局部变量,那么你就会遇到指针指向无效内存的问题。