数组大小调整和realloc功能 [英] Array resizing and realloc function

查看:114
本文介绍了数组大小调整和realloc功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我试着提高自己的三分球由理查德·里斯阅读的了解和使用C指针,指向的知识。

Now I try to improve my knowledge of pointers reading "Understanding and Using C Pointers" by Richard Reese.

下面是这本书关于一个code例如的realloc()功能。

Here's one code example from this book concerning realloc() function.

char* getLine(void) {
    const size_t sizeIncrement = 10;
    char* buffer = malloc(sizeIncrement);
    char* currentPosition = buffer;
    size_t maximumLength = sizeIncrement;
    size_t length = 0;
    int character;

    if(currentPosition == NULL) { return NULL; }

    while(1) {
        character = fgetc(stdin);

        if(character == '\n') { break; }

        if(++length >= maximumLength) {
            char *newBuffer = realloc(buffer, maximumLength += sizeIncrement);

            if(newBuffer == NULL) {
                free(buffer);
                return NULL;
            }

            currentPosition = newBuffer + (currentPosition - buffer);
            buffer = newBuffer;
        }

        *currentPosition++ = character;
    }

    *currentPosition = '\0';
    return buffer;
}

主要的想法是读取所有的符号到缓存直到我们见面 \\ n

我们不知道的符号的总数来读取所以它的合理使用的realloc()功能扩展缓存周期性。

We don't know the total number of symbols to read so it's reasonable to use realloc() function to expand buffer periodically.

所以,扩大缓存我们使用:

char *newBuffer = realloc(buffer, maximumLength += sizeIncrement);

在这种情况下,的realloc()收益 newBuffer 指针扩大缓冲区。

In this case realloc() returns newBuffer pointer to the expanded buffer.

之后,如果的realloc()已成功调用, currentPosition 将重新计算为:

After that, if realloc() was invoked successfully, currentPosition is recalculated as:

currentPosition = newBuffer + (currentPosition - buffer);

有效期是重新计算 currentPosition 在这样的方式?

Is it valid to recalculate currentPosition in such way?

据我所知,在的realloc()调用缓存指针无效。 (参见,例如,这个)。在缓存指针的任何访问导致不确定的行为。所以...我在哪里错了?

As I know, after realloc() invocation buffer pointer is invalidated. (See, for example, this). Any access to the buffer pointer leads to the undefined behaviour. So... where am I wrong?

推荐答案

这code使未定义行为:

This code causes undefined behaviour:

currentPosition = newBuffer + (currentPosition - buffer);

指针传递到的realloc ,(基于指针和其他指针)的指针变量成为后的不确定的,这是相同的该状态未初始化的变量。

After passing a pointer to realloc, that pointer variable (and all other pointers based on that pointer) become indeterminate, which is the same status that an uninitialized variable has.

参考:C11 6.2.4 / 2:

Reference: C11 6.2.4/2:

...]的指针的值变成不确定时
  它指向(或刚刚过去的)对象达到其生命周期的结束。

[...] The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

然后,在无效指针做指针算法导致不确定的行为,C11 6.5.6 / 8:

Then, doing pointer arithmetic on an invalid pointer causes undefined behaviour, C11 6.5.6/8:

当有整型的前pression加入或减去一个指针,[...]如果指针操作数都和结果指向相同的数组对象的元素,或者一个过去的最后一个数组对象的元素,该评估也不得产生溢出;否则,这种行为是未定义

When an expression that has integer type is added to or subtracted from a pointer, [...] If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined

指针操作数不指向当时的对象。它用来指向的对象已被释放。

The pointer operand doesn't point to an object at that time. The object it used to point to has already been freed.

事实上,在所有的评估指针可能会导致不确定的行为,因为一个不确定的值可能是一个陷阱重新presentation。 (想象一下,一个系统,如果将值装入地址寄存器也执行硬件检查该地址属于这个过程)。参考文献:C11 3.19.2,6.2.6.1/5:

In fact, evaluating the pointer at all may cause undefined behaviour, since an indeterminate value may be a trap representation. (Imagine a system where loading a value into an address register also performs a hardware check that the address belongs to this process). Refs: C11 3.19.2, 6.2.6.1/5:

如果一个对象的存储值有这样一个重新presentation,由不具有字符类型左值前pression阅读,其行为是未定义

If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined

写的code正确的方法将是:


The correct way to write the code would have been:

if(++length >= maximumLength)
{
    size_t currentOffset = currentPosition - buffer;

    char *newBuffer = realloc(......
    // ...

    currentPosition = newBuffer + currentOffset;
    buffer = newBuffer;
}

(我个人使用失调的整个方式,而不是 currentPosition ,来避免这个问题完全)

(Personally I would use the offset the whole way , instead of currentPosition, to avoid this problem entirely)

这篇关于数组大小调整和realloc功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆