如何将char数组作为函数和memcpy的引用传递给

时间:2012-02-08 19:01:23

标签: c++ c pass-by-reference memcpy

从早上起我一直在努力解决这个问题。值'pd' pm不会在函数外部更改。有人能告诉我这个错误是什么吗?

void foo(u8 *pm, u8 *pd) 
{
    pm = "IWR ";
    memcpy(pd, pm, sizeof(pm));
    printf("in foo pm = %s, pd = %s \n", pm, pd);
}

int main()
{
    u8 pm[5] = "0";
    u8 pd[5] = "IWO ";
    printf("pm = %s, pd = %s \n", pm, pd);  
    foo(pm, pd);
    printf("after pm = %s, pd = %s \n", pm, pd);
}

调用foo后的最终输出是pm =(null)和pd =“IWO”。我认为'pm'也会改变价值。

(以下是ideone上的代码,但在这种情况下,pm打印为0,而不是(null)。为什么会这样?)

pm = 0, pd = IWO  
in foo pm = IWR , pd = IWR  
after pm = 0, pd = IWR  

3 个答案:

答案 0 :(得分:4)

    函数sizeof(pm)中的
  1. foo()是指针的大小。不是数组的大小,因为它看起来像你在假设。
  2. 我想你的意思是pm不会在函数之外发生变化,因为给定你的程序,pd肯定会这样做。 pm没有改变的原因是因为C(以及你使用C ++的方式)是一种按值传递的语言。 C FAQ有一个question about precisely your problem

答案 1 :(得分:1)

您可以使用模板通过引用传递数组:

template<typename T, unsigned int Length1, unsigned int Length2>
void foo(T(&pm)[Length], T(&pd)[Length2]) {
    memcpy(pd, "IWR ", Length2 - 2); // - 2 for the NULL
    pd[Length2 - 1] = 0;

    printf("in foo pm = %s, pd = %s \n", pm, pd);
}

使用它与之前使用foo的方式相同。请注意,这只适用于数组,而不适用于指针。

请注意

pm = "IWR ";

在原始函数中没有做任何事情(只修改本地指针变量)并且在这个修改过的函数中不起作用(不能分配给数组)。如果你想这样做,你也必须使用memcpy

如果你不想使用模板,那么你必须将每个数组的大小传递给函数(或使用sentinel值,但不要),因为当你将数组传递给函数时(没有通过引用传递它)它衰减到一个指针,而sizeof(array)将给你一个数组中的字节数,sizeof(pointer)只给你一个指针的字节数,这不是你想要的

答案 2 :(得分:0)

嗨,通过pm =“IWR”,你已经改变了pm指向const引用的内容。即,你已经完全改变指针pm(在函数内部)指向不同的位置。

if you do this inside the function your code would work as expected. See why its failing below.


    pm[0] = 'I';
    pm[1] = 'W';
    pm[2] = 'R';

    before foo in main
    ----------
     print pm "0\000\000\000"
     print &pm ==  (u8 (*)[5]) 0x7fbffff7b0

    in foo as soon as we enter
    ------
     print pm = (u8 *) 0x7fbffff7b0 "0" (you are pointing to the same location as in main )
     print pm = (u8 **) 0x7fbffff788

    ----     pm = "IWR" ---
   print pm = 0x400adc "IWR" (now pm is pointing to location in memory where const IWR is stored )
   print &pm = (u8 **) 0x7fbffff788

   ---back to main ---
     print pm =  "0\000\000\000" ( we havent changed anything on location fff7bo so no affect )
     print &pm $8 = (u8 (*)[5]) 0x7fbffff7b0 

Google更改链接列表的头部,您应该能够找到正确的解释

cslibrary.stanford.edu/103/LinkedListBasics.pdf [看看改变头部指针]