2

我正在尝试分配一块内存,然后将数据复制到该空间中。我做了这个简单的程序,但它并没有做我期望的事情。有人可以指出我的错误推理。

谢谢。

#include <stdio.h>
#include <stdlib.h>

void main(void)
{
int t1 = 11;
int t2 = 22;
int *bufptr;

bufptr = calloc(2, sizeof(int));
if(bufptr == NULL)
{
    fprintf(stderr, "Out of memory, exiting\n");
    exit(1);
}

memcpy(bufptr, &t1, sizeof(int));
memcpy((bufptr+sizeof(int)), &t2, sizeof(int));

printf("bufptr11: %d\n", *bufptr);
printf("bufptr22: %d\n", *bufptr+sizeof(int));
}

它打印出来的内容如下:
bufptr11: 11
bufptr22: 15(这应该是 22 而不是 15)

感谢大家的帮助,但我遇到了下一个障碍!这个练习的重点是通过 udp 将一些数据发送到另一台主机。我在调用 sendto() 之前查看了 bufptr 的内容,一切看起来都很好,并且发送似乎很顺利。另一方面(我在 127.0.0.1 上运行客户端/服务器)我只收到“废话”。我调用 recvfrom(s_fd、bufptr、buflen 等)。我使用相同的 calloc 调用为 bufptr 分配内存。这个调用返回了适量的数据,但它的内容都是垃圾!

bufptr = calloc(2, sizeof(int));
if(bufptr == NULL)
{
   fprintf(stderr, "Out of memory, exiting\n");
   exit(1);
}

buflen = 2*sizeof(int);

rc = recvfrom(sd, bufptr, buflen, 0, (struct sockaddr *)&serveraddr, &serveraddrlen);
printf("t2: %d\n", *bufptr);
printf("t3: %d\n", *(bufptr+1));
4

4 回答 4

5

printf("bufptr22: %d\n", *(bufptr+sizeof(int)));

编辑:比括号更阴险的是一个事实(我一开始显然错过了)你实际上过度使用了指针算术。编译器已经将 bufptr + x 调整为 bufptr + (x * sizeof(int)) 字节。所以当你这样做时,bufptr + sizeof(int)你实际上是在超出分配的内存。

你可以看到这个:

printf("bufptr: %p\n", bufptr);
printf("bufptr + sizeof(int): %p\n", bufptr + sizeof(int));

例如对于我(32 位机器)它输出:

bufptr: 0x876f008
bufptr + sizeof(int): 0x876f018

相隔16 个字节,当时我总共只分配了 8 个!提醒比bufptr[1]看起来更有用。

这是一种可怕的错误,一开始通常不会出现,然后在您修改不相关的代码时开始导致崩溃。 valgrind会抓住它。

于 2010-02-03T11:49:32.960 回答
2
printf("bufptr22: %d\n", *bufptr+sizeof(int));

这被解释为 (*bufptr) + sizeof(int)。这给了你 11 + 4 来制作你所看到的 15。

printf("bufptr22: %d\n", *(bufptr+sizeof(int)));

如果你想把 22 拿回来,那就是你所追求的。

于 2010-02-03T11:50:45.087 回答
1

试试这些:

memcpy(bufptr, &t1, sizeof(int)); // copy 11 into the first element of the array.
memcpy(bufptr+1, &t2, sizeof(int)); // bufptr+1 will point to the next int of the array.

printf("bufptr11: %d\n", *bufptr);
printf("bufptr22: %d\n", *(bufptr+1)); // parenthesis needed as * has higher precedence than +
于 2010-02-03T11:53:46.420 回答
0

这:

memcpy((bufptr+sizeof(int)), &t2, sizeof(int));

是错误的,因为当您添加到指针时,您添加的单位是指针指向的类型的大小。在这种情况下,int。所以不需要涉及sizeof,直接使用“对象”(ints)的数量即可:

memcpy(bufptr + 1, &t2, sizeof(int));

此外,最好使用指针而不是重复类型名称,这样可以保护您将来如果它应该更改:

memcpy(bufptr + 1, &t2, sizeof *bufptr);

在后一种情况下,使用目标指针的大小通常是一个好主意,因为如果源指针类型应该更改,这可以保护您(至少有一点)不被覆盖。它们当然应该是相同的,但仍然是。

于 2010-02-03T11:56:44.900 回答