【问题标题】:Manipulating pointers to arbitary locations [closed]操纵指向任意位置的指针[关闭]
【发布时间】:2016-08-29 00:51:31
【问题描述】:

我有一个返回一个数据字的函数,我需要把它放在一个结构中;但是,当我操作任何指针时,我不在正确的边界上。

对我来说可能更容易展示:

void grab_object(size_t copies, struct iovec *iov)
{


  union u {
    long val;
    char chars[WORD_SIZE];
  }data;

  iov = malloc(sizeof(struct iovec) * copies);

  size_t numWords = (sizeof(struct iovec) * copies) / WORD_SIZE;

  if(DEBUG)
  {
    printf("numWords %zx\n", numWords);
    printf("size of word %zx\n", WORD_SIZE);
  }

  size_t x = 0;
  for(x = 0; x < copies; x++)
  {
    size_t i = 0;
    struct iovec *laddr = iov;
    while(i <= numWords)
    {

        data.val = function()
        memcpy(laddr, data.chars, WORD_SIZE);
        laddr += WORD_SIZE;
        i++;
    }

    size_t remainder = size % (WORD_SIZE);
    if(remainder != 0)
    {
      data.val = function();
      memcpy(laddr, data.chars, remainder);
    }
  }
}

这会将数据复制到结构的第一个元素中;但是,它不会在第二个。

当我打印元素和 laddr 的地址时,我得到类似于以下内容:

iov_len loc: 0x9a5148
starting laddr: 0x9a5140
after incrementing laddr: 0x9a5150
iov_len loc: 0x9a5148
starting laddr: 0x9a5150
after incrementing laddr: 0x9a5160

那么为什么 laddr 递增 0x10 而不是 1,我将如何复制“中间”数据 (iov_len)?

【问题讨论】:

  • 该代码似乎会无限递归-它以void function()开头,在for()循环的第一行你有_U.val = function();-它调用function(),它开始另一个for() 循环调用 function()
  • 你需要发布一套完整的实际编译的代码。见Minimal Complete Verifiable Example
  • @user3386109 已更新
  • laddr 递增0x10,显然是sizeof(struct iovec)
  • 这个不完整的代码中有很多错误。从哪儿开始...?您的描述中“边界”的定义是iov-&gt;iov_len 成员的地址吗?如果是,为什么您认为iov_leniov 中的第一个元素?函数签名是什么样的,您希望如何使用它? size 来自哪里?为什么函数底部有无限循环?为什么在循环结束时将laddr 增加到另一个struct iovec 的(可能)无效位置?

标签: c pointers memory-management


【解决方案1】:
char *chars[sizeof(long)];

声明指向字符的指针数组。

你应该改写

char chars[sizeof(long)];

PS:原作者修复了这个问题,但他的代码有更多问题。

【讨论】:

  • 你是对的,我的代码中就是这样。我只是没有正确复制它。
  • 制作一个有效的代码(除了问题),然后用鼠标复制它。目前,在“struct *data = malloc(sizeof(struct));”中,sizeof(struct) 没有意义,因此代码甚至无法编译。我不知道你在复制过程中犯了多少错误。
【解决方案2】:

所以正如 user31264 所暗示的,laddr 的大小增加了 struct iovec

简单的解决方案是使用一个数据类型,将大小均匀划分为struct iovec。幸运的是,char 总是 1 个字节。所以:

char *laddr = (char *)iov;

声明我们的容器和

laddr += sizeof(long);

增加一个字。

【讨论】:

  • ...谁对我自己的答案投了反对票?至少留下评论为什么它不好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 2013-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-27
相关资源
最近更新 更多