【问题标题】:Is this pointer return safe?这个指针返回安全吗?
【发布时间】:2019-06-12 12:11:31
【问题描述】:

几天前,我想找到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] == '\0' || 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 != '\0')
        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 指针设置为已在函数中本地定义的变量,这不是不安全吗?
这是否意味着一旦转换完成并且局部变量超出范围,它可能会被覆盖并且我们不能再依赖该值?

我可能只是遗漏了一些东西,但是目前我不明白这是一种安全的解决方法。

【问题讨论】:

    标签: c pointers scope atoi


    【解决方案1】:

    out 参数是一个指针,指向main 中的变量i。当您稍后执行此操作时:

    *out = l;
    

    这不会改变out,而是取消引用它并改变它指向的变量,即main中的i。所以当函数返回时i被修改了。

    如果out 指向str2int 中的一个局部变量,那么就会出现指针指向无效内存的问题。

    【讨论】:

      【解决方案2】:

      *out = l; 不设置out,它设置*out。即,无论out 已经指向的是什么,因为它取消引用指针。只要传入一个有效的地址,函数就会修改一个非本地对象。

      【讨论】:

        猜你喜欢
        • 2018-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多