首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >指针指向指针的地址和算术

指针指向指针的地址和算术
EN

Stack Overflow用户
提问于 2015-05-08 12:24:55
回答 2查看 144关注 0票数 2

程序员!

我完全沉浸在双指针(指针到指针)中…这里有很多问题!

让我们从这个任务开始:我正在编写自定义版本的'calloc‘func,它必须返回指向大小为' size’的'n‘个内存元素的指针。这是我发明的:

代码语言:javascript
复制
void **calloc1(int n, int size)
{
    int i, j;
    char *tmp, **p = NULL;
    tmp = (char *) malloc1(n * size);
    p = tmp;
    for (i = 0; i < n; i++) {
        p[i] = tmp;
        for (j = 0; j < size; j++)
            tmp++;
    }
    p = &p[0];
    return (void **)p;
}
/* I entered n==4, size==3;  real pointers are: p[0] == 0x804cfe0; p[1] == 0x804cfe3; p[2] == 0x804cfe6; ... */

因此,基本上我分配了n*个大小的字节,然后将等于'size‘的指针数组“分配”到相应的起始位置。让我们输入n=4和size=3;它表示p指向tmp,p1指向tmp3,p2指向tmp6等等。在GDB中,我几乎在每一步之后都会跟踪指针值。

然后,在“main”中,我声明了一个双指针,并将其“附加”到从我的“calloc”接收的buffer中:

代码语言:javascript
复制
int main (short argc, char **argv)
    {
        char **space;
        space = (char **) calloc1(n, size);   /* removing '(char**)' here does not have effect */ 

    /*  at this stage pointers seems to be correctly "located": 'space' == 'space[0]' == 0x804cfe0; 'space[1]' == 0x804cfe3; 'space[2]' == 0x804cfe6; ... */

1)这里已经是第一个问题了:“main()”(或者我将传递一个**p副本的任何其他函数)如何知道指针算法的大小?

好的,我们继续,我试着把一些字符放到已获取的缓冲区中:

代码语言:javascript
复制
int i = 0, j = 0, n, size;
char nn, ssize, c, temp[3];

printf ("Enter number/size \n");
sc = scanf ("%c/%c", &nn, &ssize);
n = nn - '0';  /* n==4 */
size = ssize - '0';   /* size==3 */ 

printf ("Enter a 'number' of words\n");
while (j < n) {
    for (i = 0; (c = getchar()) != EOF && i < size; i++)
        *(*space)++ = c; 
    (*space)--;   /* this line is unneccesary; if I remove it - nothing changes */
    ++j;
    ++space;
}

2)这是第一个问题的证据:实际上,当我在这里增加“空格”时,它不是按3个字符移动,而是按4个字符移动(在第一个“++”之后,它是0x804cfe4,在第二个0x804cfe8之后)。为什么?与“浮动”类型的大小有什么联系吗?在第一次递增之后,'*space‘指向0x804cfe6...我不认为这是正确的。

我尝试了另一种方式--引用“space”,而不是指针,而是数组:

代码语言:javascript
复制
....
while (j < n) {
    for (i = 0; (c = getchar()) != EOF && i < size; i++)
        *space[j]++ = c; 
    space[j]--;
    ++j;
}

3)在这种情况下,指针似乎没问题-例如space1 == 0x804cfe3,space2 == 0x804cfe6。问题是,当这个循环使用j 2操作时,“==”的值不知何故从0x804cfe2 (移动了两次- ok)变成了类似0x6a04cfe2的值(越界了)。这是什么..。???

4)而且,地址有一些奇怪的行为。我还尝试不将字符直接写入**空格,而是使用字符串复制函数:

代码语言:javascript
复制
    char i, temp[3];  
    ...
    while (j < n) {
        for (i = 0; (c = getchar()) != EOF && i < size; i++)
            temp[i] = c; 
        strncpy1 (space[j],temp,3);
        ++j;
    }
.....
void strncpy1 (char *s, char *t, int k)
{
    while (--k > 0) {
        *s = *t;
        s++;  t++;
    }
}

在复制函数中,复制和递增在GDB中显示正确。但是从'strncpy1‘返回后,spacej从0x804cfe0变成类似0x804000a的东西。被调用的函数怎么可能会影响父母的(外部)指针呢?

那么最后,指向字符的指针是什么类型呢?它有多大的尺寸?

EN

回答 2

Stack Overflow用户

发布于 2015-05-08 12:51:11

我相信在你的系统中指针的大小是4,因为你使用一个指针指向指针,然后增加它,所以它将4个字节添加到当前位置,以到达其类型(char**)的下一个指针。

注意:您不是在递增指向char的指针,而是在递增指向指针的指针。

现在再说一遍,如果我谈到你的第二个问题,函数如何知道在哪里加4,在哪里加7,所以这和函数无关。因为保存在连续位置指针地址的指针数组(它们不是指针的值,我说的是保存在指针数组中的指针),所以它只会将指针递增1,并将到达其类型的下一个指针,无论它是在P、P4还是p7上。

票数 1
EN

Stack Overflow用户

发布于 2015-05-08 12:57:25

最大的问题是指针和数据使用相同的内存位置。这就是为什么你会看到这种奇怪的行为。

您只需分配一个缓冲区,然后使用此缓冲区来包含指向同一缓冲区的指针。当然,当您随后修改内容时,您的指针也会发生变化。您必须有单独的内存位置:一个用于数据,另一个用于指向该数据的指针。

如果你真的想这样做,你可以这样做:

代码语言:javascript
复制
void **calloc1(int n, int size)
{
    int i, j;
    char *tmp, **p = NULL;
    tmp = (char *) malloc1(n * size);
    p = (char**) malloc1(n * sizeof(char*));
...

注意:这样你自然需要两次调用来释放内存,而且你可能无法知道第二次调用是什么,因为用户可以改变指针。因此,更好的做法是将这些分配合并为一个:

代码语言:javascript
复制
void **calloc1(int n, int size)
{
    int i, j;
    char *tmp, **p = NULL;
    p = (char**) malloc1(n * size + n * sizeof(char*));
    tmp = (char *) (p + n);
...

这样,就有了p指向的一个分配,但指针将有独立于实际项目的内存。

至于其他问题:

1)“main()”如何知道指针算法的大小?

指针总是有固定的大小。它们是指针,它们不关心它们所指的是什么。sizeof(char*) == sizeof(int*) == sizeof(你的冷却结构*)

空格2)当我在这里增加‘

’时,它不是移动3个字符,而是移动4个字符(在第一个'++‘之后是0x804cfe4,在第二个0x804cfe8之后)。为什么?与“浮动”类型的大小有什么联系吗?

因为在你的系统中sizeof(指针) ==为4,所以每个指针占用4个字节。在32位环境中是正常的,与浮点数、整型或任何其他类型无关。

3)当此循环使用j == 2操作时,“space”的值以某种方式从0x804cfe2 (移动两次- ok)更改为类似0x6a04cfe2的值(越界)。这是什么..。???

因为指针和数据使用相同的内存。将'j‘(十六进制的0x6A)写入space1,它指向分配的第四个字节。它也是空间指针的最高有效字节,所以它变成了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30115732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档