程序员!
我完全沉浸在双指针(指针到指针)中…这里有很多问题!
让我们从这个任务开始:我正在编写自定义版本的'calloc‘func,它必须返回指向大小为' size’的'n‘个内存元素的指针。这是我发明的:
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中:
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副本的任何其他函数)如何知道指针算法的大小?
好的,我们继续,我试着把一些字符放到已获取的缓冲区中:
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”,而不是指针,而是数组:
....
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)而且,地址有一些奇怪的行为。我还尝试不将字符直接写入**空格,而是使用字符串复制函数:
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的东西。被调用的函数怎么可能会影响父母的(外部)指针呢?
那么最后,指向字符的指针是什么类型呢?它有多大的尺寸?
发布于 2015-05-08 12:51:11
我相信在你的系统中指针的大小是4,因为你使用一个指针指向指针,然后增加它,所以它将4个字节添加到当前位置,以到达其类型(char**)的下一个指针。
注意:您不是在递增指向char的指针,而是在递增指向指针的指针。
现在再说一遍,如果我谈到你的第二个问题,函数如何知道在哪里加4,在哪里加7,所以这和函数无关。因为保存在连续位置指针地址的指针数组(它们不是指针的值,我说的是保存在指针数组中的指针),所以它只会将指针递增1,并将到达其类型的下一个指针,无论它是在P、P4还是p7上。
发布于 2015-05-08 12:57:25
最大的问题是指针和数据使用相同的内存位置。这就是为什么你会看到这种奇怪的行为。
您只需分配一个缓冲区,然后使用此缓冲区来包含指向同一缓冲区的指针。当然,当您随后修改内容时,您的指针也会发生变化。您必须有单独的内存位置:一个用于数据,另一个用于指向该数据的指针。
如果你真的想这样做,你可以这样做:
void **calloc1(int n, int size)
{
int i, j;
char *tmp, **p = NULL;
tmp = (char *) malloc1(n * size);
p = (char**) malloc1(n * sizeof(char*));
...注意:这样你自然需要两次调用来释放内存,而且你可能无法知道第二次调用是什么,因为用户可以改变指针。因此,更好的做法是将这些分配合并为一个:
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,它指向分配的第四个字节。它也是空间指针的最高有效字节,所以它变成了。
https://stackoverflow.com/questions/30115732
复制相似问题