calloc 并使用 c 将数据复制到内存区域
我正在尝试分配一块内存,然后将数据复制到该空间中。我编写了这个简单的程序,但它没有达到我的预期。有人可以指出我的错误推理吗?
谢谢。
#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 上运行客户端/服务器)我只收到“crap”。我调用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));
I'm trying to allocate a block of memory and then copy data into that space. I made this simple program and it doesn't do what I expect it to do. Could someone please point out my faulty reasoning.
Thanks.
#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));
}
What it prints out is the following:
bufptr11: 11
bufptr22: 15 (this should be 22 and not 15)
Thanks for all the help everybody, but I just ran into my next snag!
The whole point of this exercise is to send some data via udp to another host. I look at the content of the bufptr before I call sendto(), everything looks fine and the sending seems to go well. On the other side (I'm running client/server on 127.0.0.1) I just receive "crap". I call recvfrom(s_fd, bufptr, buflen, etc). I use the same calloc call for allocating memory for bufptr. There is the right amount of data being returned from this call, but the content of it is all just rubbish!
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));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
printf("bufptr22: %d\n", *(bufptr+sizeof(int)));
编辑
:比括号更阴险的是(我一开始显然错过了)您实际上过度执行了指针算术。编译器已将 bufptr + x 调整为 bufptr + (x * sizeof(int)) 字节。因此,当您执行 bufptr + sizeof(int) 时,您实际上超出了分配的内存。
您可以通过以下方式看到这一点:
例如,对于我(32 位机器),它输出:
16 个字节分开,而我总共只分配了 8 个字节!比
bufptr[1]
更有用的提醒比看起来更有用。这是一种可怕的错误,通常一开始不会显现出来,然后当您修改不相关的代码时就会开始导致崩溃。 valgrind 会捕获它。
printf("bufptr22: %d\n", *(bufptr+sizeof(int)));
EDIT: Much more insidious than the parens is the fact (which I obviously missed at first) that you are actually overdoing the pointer arithmetic. The compiler already adjusts bufptr + x to be bufptr + (x * sizeof(int)) bytes. So when you do
bufptr + sizeof(int)
you are actually overshooting the allocated memory.You can see this with:
E.g. for me (32-bit machine) it outputs:
16 bytes apart, when I only allocated 8 total! A reminder than
bufptr[1]
is more useful than it looks.This is the kind of horrible bug that often doesn't manifest at first, then starts causing crashes when you modify unrelated code. valgrind will catch it.
这被解释为 (*bufptr) + sizeof(int)。这给你 11 + 4 等于你看到的 15。
如果你想找回 22,这就是你所追求的。
That's being interpreted as (*bufptr) + sizeof(int). Which gives you 11 + 4 to make the 15 you're seeing.
That's what you're after if you're trying to get the 22 back.
试试这些:
Try these:
这
是错误的,因为当您添加到指针时,您添加的单位是指针所指向的类型的大小。在本例中为
int
。所以不需要涉及sizeof
,直接使用“对象”(int
)的数量即可:另外,最好使用指针而不是重复类型名称,如果它将来发生变化,这可以保护您:
在后一种情况下,使用目标指针的大小通常是一个好主意,因为这可以保护您(至少一点)不被覆盖源指针类型是否应更改。它们当然应该是相同的,但仍然如此。
This:
is wrong, since when you add to a pointer, you add in units of the size of the type the pointer is pointing at. In this case,
int
. So there's no need to involvesizeof
, just use the number of "objects" (int
s) directly:Also, it's better to use the pointer rather than repeating the type name, this protects you if it should change in the future:
In the latter case, it's generally a good idea to use the size of the destination pointer, since that protects you (at least a bit) against overwrite if the source pointer type should change. They should of course be the same, but still.