如何获取函数返回值的指针?

时间:2013-08-17 09:20:47

标签: c pointers return-value

功能

我正在使用函数uint32_t htonl(uint32_t hostlong)将uint32_t转换为网络字节顺序。

我想做什么

我需要在将变量转换为网络字节顺序后对变量进行计算:

//Usually I do calculate with much more variables and copy them into a much
// larger buff - to keep it understandable and simple I broke it down 
// to one calculation

uint32_t var = 1;
void* buff;

buff = malloc(sizeof(uint32_t));

while(var < 5) {
    var = htonl(var);
    memcpy(buff, &var, sizeof(uint32_t));
    doSomethingWithBuff(buff);
    var++; // FAIL
}

我能做什么,但......

实际上我已经找到了解决这个问题的方法:

uint32_t var = 1, nbo;
void* buff;

buff = malloc(sizeof(uint32_t));

while(var < 5) {
    nbo = htonl(var);
    memcpy(buff, &nbo, sizeof(uint32_t));
    doSomethingWithBuff(buff);
    var++;
}

问题是我用这个解决方案浪费了内存,因为nbo只是用作缓冲区。

我更喜欢做什么

如果我可以在memcpy()函数中使用htonl()函数,那将是完美的。 memcpy()需要第二个值为void *。我的问题是:如何获取htonl()的返回值的地址?

uint32_t var = 1;
void* buff;

buff = malloc(sizeof(uint32_t));

while(var < 5) {
    memcpy(buff, (GET ADDRESS)htonl(var), sizeof(uint32_t));
    doSomethingWithBuff(buff);
    var++;
}

如果不可能,因为“没有这个变量的地址”:函数如何工作返回变量而不是指向变量的指针?

3 个答案:

答案 0 :(得分:2)

仅讨论一个变量缓冲区


我认为你正在做错误的微优化。

正如 Uchia Itachi 指出的那样,获取返回值的地址将是一个错误。

实际上,如果您担心效率,那么瓶颈就是静态存储。 malloc()具有内存开销 - 除了存储在静态内存中的数据外,还会写入元数据。例如,here (scroll down to Implementation Details)解释了一个聪明的最小算法如何为每个分配只有size_t的开销。这甚至不考虑分裂。

memcpy()是一个快速函数,但对于单个数字也是一种过度杀伤。

因此,我建议仅使用堆栈。使buff成为全局整数变量。然后将buff,s地址传递给那些,需要一个缓冲区。他们不会注意到差异。

讨论修改过的问题 - 循环中有大量写入和读取的大缓冲区


当函数返回(某物)时,它会将值(或指向对象的指针)推送到寄存器或堆栈中。另一方面,当声明,初始化和使用变量时,它驻留在寄存器或堆栈中。

你注意到相似之处吗?优化编译器删除不需要的变量,它们还创建未命名的变量供内部使用。例如,在检测到此范围内不再引用变量后,将重用存储变量。

因此,应该努力编写简单易读的代码,并将详细信息留给编译器。这意味着你的第二个例子非常好。

答案 1 :(得分:0)

您无法确定函数的返回值将放在何处。有时,值会在堆栈上返回,有时则可能在寄存器中。返回内容与在C中返回指针之间没有真正的区别。但是不要混淆仅在不同函数中定义和访问的局部变量。这样做会增加seg故障的可能性。此外,使用&amp; nbo并不浪费内存。

答案 2 :(得分:0)

您可以使用宏来“解决”问题:

#define APPEND_TO_BUFFER( \
  buffer, \
  value, \
  type) 
  { \
    type tmpvar = (value); \
    memcpy((buffer), &tmpvar, sizeof(type)); \
  }

...

char * buff = <some valid memory address>;

uint32_t var = <some value>;
int i = <some other value>;

...

  APPEND_TO_BUFFER(buff, htonl(var), uint32_t); /* Append converted var to buffer as per OP. */
  APPEND_TO_BUFFER(buff+sizeof(uint32_t), i, int); /* Append another i right after var.  */

  doSomethingWithBuff(buff);